Сообщество программистов 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
Вот так у меня получилось сделать копию блока:

Код - Python [Выбрать]
  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 - я не проверял, но вполне возможно, что он учитывает и установленную видимость в динамическом блоке.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 27-01-2020, 12:45:21
Возможно ли в AutoCAD с помощью COM или .Net определить, что объект на чертеже (например,  отрезок или блок, как на рисунке ниже) находится внутри прямоугольной рамки-полилинии без применения математических расчетов с координатами и границами boundingbox?
Я нашел IntersectWith метод, но если применить его к блоку и синей полилинии ниже - метод просто возвращает пустой список пересечений, т.к. объекты формально не пересекаются. То же самое, если рамка выполнена блоком.

(https://i.postimg.cc/VdSqcPnX/test.jpg) (https://postimg.cc/VdSqcPnX)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 27-01-2020, 12:50:49
Код - Visual Basic [Выбрать]
  1. SelectionSet.Select acSelectionSetWindow p1 p2
Точки p1 и p2 должны быть видимы на экране.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 27-01-2020, 12:56:39
Да нет, не выделить объекты на чертеже, а определить, что уже нарисованный блок находится внутри уже нарисованной полилинии. Я так понимаю, такого метода нет, но хочу убедиться наверняка.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 27-01-2020, 13:05:25
Electric,
Ты таким образом не выделяешь, а находишь все объекты внутри окна (т.е. твоего прямоугольника). Если объект внутри окна, то он попадёт в набор, если нет - нет. Другого способа нет.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 27-01-2020, 16:08:05
Понял. Спасибо за наводку!
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 25-02-2020, 21:12:42
Добрый день!
Сталкиваюсь с такой проблемой, например, если программа довольно продолжительное время работает, существует проблема, что
если пользователь ткнет в чертеж или нажмет на клавишу, то при обращении к AutoCad выпадет исключение.
Можно ли как то заблокировать работу автокад на время работы скрипта?
Можно, конечно ловить исключения, но тогда придется ловить каждое обращение к автокаду, что сильно усложняет программу...
Может есть какой нибудь стандартный способ уйти от этого?
Ну и если есть такой, то сразу возникнет обратная задача, прервать работу скрипта и разблокировать автокад...
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 25-02-2020, 21:44:04
Можно ли как то заблокировать работу автокад на время работы скрипта?
Заблокировать через COM/ActiveX нельзя. Можно сделать его невидимым: Application.Visible = False
Ну или контролировать его состояние через Application.GetAcadState().IsQuiescent  - если True, то можно выполнять очередное действие.
Но исключения нужно ловить в любом случае.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 25-02-2020, 23:37:26
То есть получается, в любом случае нужно разбивать код на участки, отлавливать исключения и если исключение возникает, код повторять заново? Ну либо вообще все сбрасывать.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 25-02-2020, 23:46:30
То есть получается, в любом случае нужно разбивать код на участки, отлавливать исключения и если исключение возникает, код повторять заново? Ну либо вообще все сбрасывать.
Именно так. Вот пример, как это делается в C++: https://adn-cis.org/kak-ispolzuya-visual-c-zapustit-autocad-i-zastavit-ego-vyipolnyat-nekotoryie-dejstviya.html
Для Python в принципе аналогично.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 26-02-2020, 04:11:48
Добрый день!
Сталкиваюсь с такой проблемой, например, если программа довольно продолжительное время работает, существует проблема, что
если пользователь ткнет в чертеж или нажмет на клавишу, то при обращении к AutoCad выпадет исключение.
Можно ли как то заблокировать работу автокад на время работы скрипта?
Можно, конечно ловить исключения, но тогда придется ловить каждое обращение к автокаду, что сильно усложняет программу...
Может есть какой нибудь стандартный способ уйти от этого?
Ну и если есть такой, то сразу возникнет обратная задача, прервать работу скрипта и разблокировать автокад...

Я как-то для подобных целей использовал такой танец с бубном. Вставляю функцию в наиболее проблемные участки кода, когда нужно дождаться AutoCAD, а он занят черчением или может не ответить на запрос, пытаюсь получить доступ к пространству модели, иначе жду в цикле:

Код - Python [Выбрать]
  1. def dynamicPause():
  2.     wait_time = 0.1
  3.     while wait_time<10:
  4.         try:
  5.             app = win32com.client.Dispatch("AutoCAD.Application")
  6.             aDoc = app.ActiveDocument
  7.             mSp = aDoc.ModelSpace
  8.             break
  9.         except:
  10.             sleep(wait_time)
  11.             wait_time *= 2
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 26-02-2020, 12:07:14
Спасибо за ответы!

В принципе я так и так я и предполагал... просто надеялся, что может быть в автокаде есть что то для упрощения этой задачи...
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 26-02-2020, 12:08:23
А это неплохое решение, возьму на вооружение... спасибо!

Я как-то для подобных целей использовал такой танец с бубном. Вставляю функцию в наиболее проблемные участки кода, когда нужно дождаться AutoCAD, а он занят черчением или может не ответить на запрос, пытаюсь получить доступ к пространству модели, иначе жду в цикле:

Код - Python [Выбрать]
def dynamicPause():
    wait_time = 0.1
    while wait_time<10:
        try:
            app = win32com.client.Dispatch("AutoCAD.Application")
            aDoc = app.ActiveDocument
            mSp = aDoc.ModelSpace
            break
        except:
            sleep(wait_time)
            wait_time *= 2
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DFG2020 от 28-02-2020, 22:44:09
Всем добра!
Подскажите, как вставить блок в Autocad при помощи метода InsertBlock?
В VBA работала строка:

Код - Visual Basic [Выбрать]
  1. insertionPnt(0) = 377.7541: insertionPnt(1) = 304.5495: insertionPnt(2) = 0
  2. Set blockRefObj = acadDoc.ModelSpace.InsertBlock(insertionPnt, "сектор-план", 1#, 1#, 1#, a1r)

Как данную строку перевести в питон?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 28-02-2020, 22:56:03
DFG2020,
Приветствую на форуме!
Обрати внимание на правило форматирования кода у нас на форуме (у меня в подписи) и соблюдай его.
Что касается вопроса, то как-то так наверное:
Код - Python [Выбрать]
  1. import array
  2. import comtypes.client
  3. app = comtypes.client.GetActiveObject("AutoCAD.Application")
  4. ms = app.ActiveDocument
  5. files = r"сектор-план"
  6. insertionPnt = array.array('d', [377.7541,304.5495,0])
  7. ms.ModelSpace.InsertBlock(insertionPnt, files, 1, 1, 1, 0)
P.S.: На Python я не пишу. Этот код - результат двухминутного поиска в интернет.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DFG2020 от 28-02-2020, 23:31:28
Что касается вопроса, то как-то так наверное:
Получаю ошибку:
    import comtypes.client
ModuleNotFoundError: No module named 'comtypes'
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DFG2020 от 28-02-2020, 23:36:08
А если использовать
import win32com.client
т.е. так:
Код - Python [Выбрать]
  1. import win32com.client
  2. import array
  3.  
  4. app = win32com.client.Dispatch("AutoCAD.Application")
  5. acadDoc = app.ActiveDocument
  6.  
  7. files = r"сектор-план"
  8. insertionPnt = array.array('d', [377.7541,304.5495,0])
  9. acadDoc.ModelSpace.InsertBlock(insertionPnt, files, 1, 1, 1, 0)

получаю ошибку:
    acadDoc.ModelSpace.InsertBlock(insertionPnt, files, 1, 1, 1, 0)
  File "<COMObject <unknown>>", line 5, in InsertBlock
pywintypes.com_error: (-2147352567, 'Ошибка.', (0, None, None, None, 0, -2147024809), None)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DFG2020 от 28-02-2020, 23:51:06
А если использовать
import win32com.client
т.е. так:
Код - Python [Выбрать]
import win32com.client
import array
 
app = win32com.client.Dispatch("AutoCAD.Application")
acadDoc = app.ActiveDocument
 
files = r"сектор-план"
insertionPnt = array.array('d', [377.7541,304.5495,0])
acadDoc.ModelSpace.InsertBlock(insertionPnt, files, 1, 1, 1, 0)

получаю ошибку:
    acadDoc.ModelSpace.InsertBlock(insertionPnt, files, 1, 1, 1, 0)
  File "<COMObject <unknown>>", line 5, in InsertBlock
pywintypes.com_error: (-2147352567, 'Ошибка.', (0, None, None, None, 0, -2147024809), None)

Нашел решение, правда сам не до конца понял, как оно работает, но оно работает!))

Код - Python [Выбрать]
  1. import win32com.client
  2. import pythoncom
  3.  
  4. def POINT(x,y,z):
  5.     return win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, (x,y,z))
  6.  
  7. acad = win32com.client.Dispatch("AutoCAD.Application")
  8. doc = acad.ActiveDocument
  9. ms = doc.ModelSpace
  10. files = "сектор-план"
  11. doc.Utility.Prompt("hello World\n")
  12. pt1= POINT(0.0,0.0,0.0)
  13. ms.InsertBlock(pt1, files, 1.0,1.0,1.0, 0)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 29-02-2020, 00:33:41
правда сам не до конца понял, как оно работает, но оно работает!
Функция POINT на основе переданных трёх чисел (x, y, z) формирует VARIANT, соответствующий массиву (VT_ARRAY) из чисел типа double (плавающие с двойной точностью VT_R8). Ну а дальше всё аналогично тому примеру, который я давал.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DFG2020 от 02-03-2020, 21:30:30
Спасибо, Александр!

Не смог найти кнопку Решение, подскажите, где она.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 02-03-2020, 21:37:24
DFG2020,
Кнопка <<Решение>> есть только у того, кто создал тему и у Администраторов/Модераторов. Так что у вас в распоряжении только кнопочки [+].
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 04-03-2020, 08:25:00
Существует ли способ программно определить не пользовательскую, а фактическую ширину MText? Т.е. размеры выделенной области с текстом, а не саму ширину рамки-рулетки на рисунке:
(https://i.postimg.cc/LnMPtVDB/image.png) (https://postimg.cc/LnMPtVDB)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Владимир Шу от 04-03-2020, 09:00:11
В VBA, такое не сделали, а вот в .NET вроде бы есть:
MText.ActualHeight
MText.ActualWidth
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DFG2020 от 23-03-2020, 22:34:02
Всем здоровья!)

Подскажите, как в существующий блок в пространстве модели добавить элементы из другого блока, удалив все элементы первого? Или вставить в него весь существующий блок, если так легче, опять же удалив все элементы первого. 

Спасибо!
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 23-03-2020, 22:39:57
Всем здоровья!)

Подскажите, как в существующий блок в пространстве модели добавить элементы из другого блока, удалив все элементы первого? Или вставить в него весь существующий блок, если так легче, опять же удалив все элементы первого. 

Спасибо!

Посмотри метод CopyObjects для копирования объектов из одного блока в другой (есть пример в этой теме). Ну а ненужное потом удалишь.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DFG2020 от 24-03-2020, 00:01:47
Посмотри метод CopyObjects для копирования объектов из одного блока в другой (есть пример в этой теме).
У блока нет метода CopyObjects, в примере этот метод применяется к документу и , как я понял, создается копия блока в документе, но мне нужно "перезаписать" содержимое уже существующего блока.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 24-03-2020, 00:35:02
Посмотри метод CopyObjects для копирования объектов из одного блока в другой (есть пример в этой теме).
У блока нет метода CopyObjects, в примере этот метод применяется к документу и , как я понял, создается копия блока в документе, но мне нужно "перезаписать" содержимое уже существующего блока.
Ну значит ты не понял как работает этот метод. Ему нужно указать какой объект будет владельцем новых копий объектов. Вот этим владельцем и должен стать второй блок. Ну а из первого ничего удалять не нужно, так как ты собираешься удалить сам этот блок. В этом случае ты должен будешь сначала удалить все вставки (BlockReference) первого блока, а затем удалить сам блок (из таблицы Blocks)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DFG2020 от 24-03-2020, 23:48:14
Ну значит ты не понял как работает этот метод. Ему нужно указать какой объект будет владельцем новых копий объектов. Вот этим владельцем и должен стать второй блок. Ну а из первого ничего удалять не нужно, так как ты собираешься удалить сам этот блок. В этом случае ты должен будешь сначала удалить все вставки (BlockReference) первого блока, а затем удалить сам блок (из таблицы Blocks)

пробую назначить владельца - блок 1, но не выходит, не тот тип данных для владельца, пробовал и первый блок перевести в массив, но тоже не тот тип данных. В примере выше есть строка: b_name = f"{o_blk.Name}_{i:02d}", это на JSON. Как это интерпретировать для питона?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DFG2020 от 24-03-2020, 23:50:12
Пример, как я пробовал. Подскажите, как что можно исправить.

Код - Python [Выбрать]
  1. import win32com.client
  2. import pythoncom
  3.  
  4. app = win32com.client.Dispatch("AutoCAD.Application")
  5. acadDoc = app.ActiveDocument
  6. mSp = acadDoc.ModelSpace
  7.  
  8. block_1 = acadDoc.Blocks.Item("блок 1")
  9. block_2 = acadDoc.Blocks.Item("блок 2")
  10.  
  11. lst_1 = [e for e in block_1]
  12. lst_2 = [e for e in block_2]
  13.  
  14. def BLOCK(list):
  15.     return win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, (list))
  16.  
  17. v_lst_1 = BLOCK(lst_1)
  18. v_lst_2 = BLOCK(lst_2)
  19.  
  20. acadDoc.CopyObjects(v_lst_2, v_lst_1)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 24-03-2020, 23:52:09
В примере выше есть строка: b_name = f"{o_blk.Name}_{i:02d}", это на JSON. Как это интерпретировать для питона?
Это к теме не имеет отношения - это лишь для формата имени блока.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 24-03-2020, 23:56:19
1. Почему pythoncom.VT_R8 ???
2. Должно быть как-то так  (если копировать объекты блока 1 в блок 2):
Код - Python [Выбрать]
  1. acadDoc.CopyObjects(v_lst_1, block_2)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DFG2020 от 25-03-2020, 00:00:21
2. Должно быть как-то так  (если копировать объекты блока 1 в блок 2):
Пробовал и так. Выдает:
TypeError: float() argument must be a string or a number, not 'CDispatch'
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DFG2020 от 25-03-2020, 00:02:50
1. Почему pythoncom.VT_R8
Честно и сам не очень понимаю этот момент. Брал из другого примера для преобразования данных в массив.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 25-03-2020, 00:13:41
1. Почему pythoncom.VT_R8
Честно и сам не очень понимаю этот момент. Брал из другого примера для преобразования данных в массив.
Не нужно бездумно копипастить. Объекты AutoCAD - это не плавающие числа. Поэтому вместо pythoncom.VT_R8 должно быть (скорее всего) pythoncom.VT_DISPATCH.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 25-03-2020, 00:26:51
И вообще в этом примере есть всё, что нужно: https://adn-cis.org/forum/index.php?topic=7864.msg42066#msg42066
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 25-03-2020, 00:29:17
это на JSON
Это он случайно выбрал не тот тип форматирования - вместо Python указал JSON.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DFG2020 от 26-03-2020, 23:29:49
Не нужно бездумно копипастить. Объекты AutoCAD - это не плавающие числа. Поэтому вместо pythoncom.VT_R8 должно быть (скорее всего) pythoncom.VT_DISPATCH.
Благодарю за этот комментарий! Основная часть пройдена: в блок 1 вставились все элементы блока 2! Теперь нужно удалить (или это нужно было сделать сначала), все первоначальные элементы из блока 1. Как это можно сделать?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Алексей Кулик от 26-03-2020, 23:57:03
ИМХО лучше будет удалить все вхождения "Блок1", а потом уже удалить его описание.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DFG2020 от 27-03-2020, 00:02:21
ИМХО лучше будет удалить все вхождения "Блок1", а потом уже удалить его описание.
А это не приведет к удалению блока 1 из тех мест, где он находится в файле? Задача стоит в том, что бы элементы блока 1 заменились на элементы блока 2, при этом все местоположения блока 1 в модели должны сохраниться.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 27-03-2020, 00:14:10
Задача стоит в том, что бы элементы блока 1 заменились на элементы блока 2, при этом все местоположения блока 1 в модели должны сохраниться.
Так может достаточно у вставок блока поменять свойство Name с "Блок 1" на "Блок 2" ???
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DFG2020 от 27-03-2020, 00:19:19
Так может достаточно у вставок блока поменять свойство Name с "Блок 1" на "Блок 2"
Идея правильная, но как это сделать через питон?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 27-03-2020, 12:31:15
Так может достаточно у вставок блока поменять свойство Name с "Блок 1" на "Блок 2"
Идея правильная, но как это сделать через питон?
Выбрать все вставки блока с именем "Блок 1" и изменить им свойство Name на "Блок 2". На питоне не пишу, поэтому код не предоставлю.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DFG2020 от 01-04-2020, 12:41:35
Пробую так:
Код - Python [Выбрать]
  1. block_1 = acadDoc.Blocks.Item("блок 1")
  2. block_1.Name = 'блок 2'

Выдает ошибку. Имя можно менять только на новое, например "блок 3", тогда ошибку не выдает.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 01-04-2020, 12:45:57
Пробую так:
Код - Python [Выбрать]
  1. block_1 = acadDoc.Blocks.Item("блок 1")
  2. block_1.Name = 'блок 2'

Выдает ошибку. Имя можно менять только на новое, например "блок 3", тогда ошибку не выдает.
Имя нужно присваивать не Block (описание блока), а BlockReference (вставка блока), о чем я выше и писал.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DFG2020 от 01-04-2020, 13:44:27
Имя нужно присваивать не Block (описание блока), а BlockReference (вставка блока), о чем я выше и писал.
Ох, никак не могу понять, как применить BlockReference в питоне...
Может есть ссылка на подобные примеры?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 01-04-2020, 13:58:30
Ох, никак не могу понять, как применить BlockReference в питоне...
На питоне вообще практически нет примеров для работы с AutoCAD.
Алгоритм такой. Тебе нужно найти все BlokReference в чертеже. Для этого ты можешь воспользоваться SelectionSet.Select и указать в качестве фильтра "INSERT" (это и есть BlockReference). Дальше проходишься по всем элементам полученного набора и проверяешь свойство Name - если "Блок 1", то меняешь на "Блок 2".
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 01-04-2020, 14:14:56
Начни отсюда и еще несколько следующих сообщений: https://adn-cis.org/forum/index.php?topic=7864.msg40087#msg40087
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DFG2020 от 01-04-2020, 17:40:09
Ура! Все заработало, но без SelectionSets, и очень долго, когда в файле много объектов.
Код - Python [Выбрать]
  1. import win32com.client
  2. import pythoncom
  3.  
  4. acad = win32com.client.Dispatch("AutoCAD.Application")
  5. doc = acad.ActiveDocument
  6.  
  7. for entity in acad.ActiveDocument.ModelSpace:
  8.     name = entity.EntityName
  9.     if name == 'AcDbBlockReference':
  10.         NameAttributes = entity.Name
  11.         if NameAttributes == 'блок 1':
  12.             entity.Name = 'блок 2'

Как можно сделать значительно быстрее? Использование SelectionSets поможет убыстрить процес?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 01-04-2020, 17:43:43
Как можно сделать значительно быстрее? Использование SelectionSets поможет убыстрить процес?
Не думаю, что что-то может этот код ускорить. Разве что отказ от Python, который выполняется в отдельном процессе от AutoCAD, что приводит к замедлению.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DFG2020 от 01-04-2020, 17:58:37
Не думаю, что что-то может этот код ускорить.
Может быть как-то можно сделать перебор не всех элементов в Модели, а только вставок блока?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 01-04-2020, 19:34:56
Не думаю, что что-то может этот код ускорить.
Может быть как-то можно сделать перебор не всех элементов в Модели, а только вставок блока?
А это как раз можно, но только через SelectionSet
Название: Re: Python & ActiveX/COM Autocad
Отправлено: mvv_010 от 02-04-2020, 22:53:15
Код - Python [Выбрать]
  1. from comtypes.client import CreateObject, GetActiveObject
  2. from array import array
  3.  
  4. try:
  5.     acad = GetActiveObject("AutoCAD.Application", dynamic=True)
  6. except:
  7.     acad = CreateObject("AutoCAD.Application", dynamic=True)
  8.  
  9. try:
  10.     select = acad.ActiveDocument.SelectionSets.Add("SSET_Blocks")
  11. except:
  12.     select = acad.ActiveDocument.SelectionSets.Item("SSET_Blocks")
  13.     select.Clear()
  14.  
  15. # all_block = [block.Name for block in acad.ActiveDocument.Blocks]
  16. # Имена всех блоков в чертеже включая ModelSpace и PaperSpace
  17.  
  18. Name_Block = ""# Имя вашего блока
  19. FilterType = array("h", [0, 2])# Коды в документации к DXF
  20. FilterDate = ["INSERT", Name_Block]
  21. SelectAll = 5# Режим выбора
  22. point = array("d", [0, 0, 0])
  23.  
  24. select.Select(SelectAll, point, point, FilterType, FilterDate)
  25. print("Select blocks:", select.Count)
  26. for obj in select:# Перебор выбранных элементов
  27.     pass
  28.  
  29. acad = None
  30.  
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 02-04-2020, 23:03:58
mvv_010,
Код 100 не нужен. И вообще фильтрация по этому коду не работает в большинстве случаев.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DFG2020 от 04-04-2020, 01:19:41
Подскажите, как можно поменять прорисовку текста, а точнее вынести на передний план?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 04-04-2020, 15:01:10
Подскажите, как можно поменять прорисовку текста, а точнее вынести на передний план?
Посмотри в документации метод MoveToTop. Там и пример есть на VBA: https://knowledge.autodesk.com/ru/search-result/caas/CloudHelp/cloudhelp/2016/RUS/AutoCAD-ActiveX/files/GUID-0FA80CF9-427C-40F1-A400-BFD4AE81EE99-htm.html
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 10-04-2020, 15:16:01
Доброго дня!
Подскажите, куда копать,
У меня в чертеже два блока, разбиваю оба функцией

Код - Python [Выбрать]
  1. blk.Explode()

При этом оба блока разбиваются, но при выполнении этой функции с одним из блоков, функция возвращает список элементов получившихся при рабивании,
а для другого блока возвращается пустой список. Причем фактически в чертеже оба блока разбиваются. Есть ли идеи с чем это может быть связано? (Может быть связано с масштабами?)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 10-04-2020, 15:19:44
DMuzer,
Нужно смотреть на блоки.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 10-04-2020, 15:20:18
Да, странное дело, у того блока, который не возвращал массива элементов установлен масштаб 110, меняю на 100, функция начинает возвращать элементы.
Почему?
Выяснилась такая штука, ошибочно  масштаб по Z отличался от масштабав по Х и Y. В этой ситуации функция не возвращает списка объектов.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 10-04-2020, 15:26:35
Да, странное дело, у того блока, который не возвращал массива элементов установлен масштаб 110, меняю на 100, функция начинает возвращать элементы.
Почему?
О каком масштабе идёт речь? Есть масштабы по X,Y,Z, а есть масштаб аннотаций. Если масштабы по X,Y,Z отличаются, то Explode очень часто не срабатывает, ну и соответственно ничего не возвращает.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 10-04-2020, 15:38:38
Цитата: DMuzer от 10-04-2020, 15:20:18
Да, странное дело, у того блока, который не возвращал массива элементов установлен масштаб 110, меняю на 100, функция начинает возвращать элементы.
Почему?
О каком масштабе идёт речь? Есть масштабы по X,Y,Z, а есть масштаб аннотаций. Если масштабы по X,Y,Z отличаются, то Explode очень часто не срабатывает, ну и соответственно ничего не возвращает.

Ну видимо это как раз тот случай. Устанавливаю одинаковые масштабы, все начинает работать.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 10-04-2020, 15:41:59
Ну видимо это как раз тот случай. Устанавливаю одинаковые масштабы, все начинает работать.
Интересно, а что внутри этого блока? И какая версия AutoCAD?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Алексей Кулик от 10-04-2020, 17:35:22
И что с EXPLMODE ( https://knowledge.autodesk.com/ru/support/autocad/learn-explore/caas/CloudHelp/cloudhelp/2018/RUS/AutoCAD-Core/files/GUID-113BD30D-2F46-4E23-9B49-034AB50064A7-htm.html )?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DFG2020 от 14-04-2020, 23:33:28
Всем добра!

Подскажите, как к координатам в виде VARIANT задать смещение на заданную величину? Т.е. у меня есть точка в формате VARIANT, как задать ее смещение, т.е. изменить одну или несколько ее  параметров x или y?
Все это в питоне.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 15-04-2020, 10:21:58
Всем добра!

Подскажите, как к координатам в виде VARIANT задать смещение на заданную величину? Т.е. у меня есть точка в формате VARIANT, как задать ее смещение, т.е. изменить одну или несколько ее  параметров x или y?
Все это в питоне.
Преобразовать в массив double, изменить соответствующие элементы массива и обратно преобразовать в VARIANT.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: mvv_010 от 15-04-2020, 19:02:05
DFG2020,
Код - Python [Выбрать]
  1. def POINT(list):
  2.     return win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, (list))
  3.  
  4. # Как поменять VARIANT
  5. bl = (POINT([1,2,3]))# win32com.client.VARIANT(8197, [1, 2, 3])
  6. bl.value[0] += 10
  7. bl.value[1] += 10
  8. bl.value[2] += 10
  9. print(bl) # win32com.client.VARIANT(8197, [11, 12, 13])
  10.  
  11. # Правка координат для точки
  12. point_1 = acad.ActiveDocument.ModelSpace.AddPoint(POINT([1,2,3]))
  13. print(point_1.Coordinates) # (1.0, 2.0, 3.0)
  14. # Так как возвращается кортеж, переводим его в список и меняем.
  15. listCoordinates = list(point_1.Coordinates)
  16. listCoordinates[0] += 10
  17. listCoordinates[1] += 20
  18. listCoordinates[2] += 30
  19. point_1.Coordinates = POINT(listCoordinates)
  20. # Или так
  21. point_1.Coordinates = POINT([point_1.Coordinates[0] + 10,
  22.                      point_1.Coordinates[1] + 20,
  23.                      point_1.Coordinates[2] + 30])
  24.  
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DFG2020 от 26-04-2020, 15:33:15
Всем терпения!

Подскажите пожалуйста, как использовать Lineweight в питоне, как применить толщину acLnWt030?
В примере для VBA строка выглядит просто: Obj.Lineweight = acLnWt211
Но в питоне выдает ошибку. Как преобразовать acLnWt211 для использования в питоне?

Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 26-04-2020, 16:55:47
Как преобразовать acLnWt211 для использования в питоне?
Подставь просто целое число 211:
Код - C++ [Выбрать]
  1. enum AcLineWeight
  2.     {
  3.         acLnWt000       = 0,
  4.         acLnWt005       = 5,
  5.         acLnWt009       = 9,
  6.         acLnWt013       = 13,
  7.         acLnWt015       = 15,
  8.         acLnWt018       = 18,
  9.         acLnWt020       = 20,
  10.         acLnWt025       = 25,
  11.         acLnWt030       = 30,
  12.         acLnWt035       = 35,
  13.         acLnWt040       = 40,
  14.         acLnWt050       = 50,
  15.         acLnWt053       = 53,
  16.         acLnWt060       = 60,
  17.         acLnWt070       = 70,
  18.         acLnWt080       = 80,
  19.         acLnWt090       = 90,
  20.         acLnWt100       = 100,
  21.         acLnWt106       = 106,
  22.         acLnWt120       = 120,
  23.         acLnWt140       = 140,
  24.         acLnWt158       = 158,
  25.         acLnWt200       = 200,
  26.         acLnWt211       = 211,
  27.         acLnWtByLayer   = -1,
  28.         acLnWtByBlock   = -2,
  29.         acLnWtByLwDefault       = -3
  30.     }   AcLineWeight;
  31.  
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DFG2020 от 26-04-2020, 21:01:01
Подскажите, как задать начальную и конечную ширину ломаной линии object.SetWidth SegmentIndex, StartWidth, EndWidth? Линия состоит из одного элемента.
При воспроизводстве данного метода в питоне возникает ошибка, возможно тип данных SegmentIndex не соответствует питону. SegmentIndex - тип данных Integer.
Если задавать как object.SetWidth 0, 5, 5 - ошибка "SyntaxError: invalid syntax" на первом значенни "0"
Если задавать как object.SetWidth , 5, 0 - ошибки нет, но ничего не меняется.


Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 26-04-2020, 21:13:47
Первый аргумент должен быть целым (int), а второй и третий - плавающим (double)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DFG2020 от 26-04-2020, 23:44:00
Первый аргумент должен быть целым (int)
А 0 - это не целое (int)?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 26-04-2020, 23:46:55
А 0 - это не целое (int)?
В Python - не знаю. Может long, может short. Впрочем можешь попробовать short. Но главное второй и третий аргументы должны быть double.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DFG2020 от 26-04-2020, 23:50:16
В Python - не знаю. Может long, может short. Впрочем можешь попробовать short. Но главное второй и третий аргументы должны быть double.
Первый аргумент ставлю 0, но питон ругается именно на него:
    arrow_B.SetWidth 0, 5, 5
                               ^
SyntaxError: invalid syntax
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 27-04-2020, 00:08:32
В Python - не знаю. Может long, может short. Впрочем можешь попробовать short. Но главное второй и третий аргументы должны быть double.
Первый аргумент ставлю 0, но питон ругается именно на него:
    arrow_B.SetWidth 0, 5, 5
                               ^
SyntaxError: invalid syntax
Так это же ошибка синтаксиса, а не типа данных. Может быть как-то так:
Код - Python [Выбрать]
  1.  arrow_B.SetWidth (0, 5.0, 5.0)
???
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DFG2020 от 27-04-2020, 00:18:46
Так это же ошибка синтаксиса, а не типа данных.
Ох, да , не отметил, что в питоне нужно добавлять скобки!

Спасибо!
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 30-04-2020, 16:28:05
Возможно я задавал этот вопрос раньше, точно не помню. В AutoCAD последних версий есть полезная возможность импортировать геометрию PDF документов, как раз появилась необходимость автоматизировать этот процесс. Существует ли какая-нибудь возможность через COM работать с этой новой функцией распознавания геометрии? Или COM слишком стар для этого?

Единственное, что я нашел, это возможность через текстовую строку отправить  команду AcadDocument.SendCommand("_-ПДФИМПОРТ "), но далее возникают проблемы с  аргументами. На запрос "Выберите подложку PDF или <Файл>" я могу отправить Ф и AutoCAD тут  же открывает графическое окно выбора файла. Если ли способ передать путь к этому файлу в виде текстовой строки вроде "F:\\target.pdf" в обход графического меню?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 30-04-2020, 17:32:08
Существует ли какая-нибудь возможность через COM работать с этой новой функцией распознавания геометрии?
Нет.
Единственное, что я нашел, это возможность через текстовую строку отправить  команду AcadDocument.SendCommand("_-ПДФИМПОРТ ")
Нужно послать такое lisp-выражение в качестве строки:
Код - Auto/Visual Lisp [Выбрать]
  1. (command "_-pdfimport" "_f" "C:/test.pdf" "1" "0,0" "1" "0")
Не забудь:
1) двойные кавычки следует сдублировать;
2) после закрывающейся круглой скобки нужен еще один пробел;
3) "C:/test.pdf" - полный путь к pdf-файлу и обратные слеши заменяем на прямые;
4) первая "1" в команде - номер страницы из pdf-файла;
5) "0,0" - точка вставки страницы;
6) вторая "1" - масштабный коэффициент;
7) "0" - угол поворота.
Наверное это будет как-то так:

Код - Python [Выбрать]
  1. AcadDocument.SendCommand('(command "_-pdfimport" "_f" "C:/test.pdf" "1" "0,0" "1" "0") ')
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 30-04-2020, 18:33:42
AcadDocument.SendCommand('(command "_-pdfimport" "_f" "C:/test.pdf" "1" "0,0" "1" "0") ')

Спасибо, это то, что нужно!
А если бы, чисто теоретически, мне потребовалось бы применить больше настроек ("Данные PDF для импорта", "Слои", "Параметры импорта"), то эти настройки так же следовало бы вписывать в эту текстовую команду? Есть ли документация на подобные lisp команды?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 30-04-2020, 18:46:49
А если бы, чисто теоретически, мне потребовалось бы применить больше настроек ("Данные PDF для импорта", "Слои", "Параметры импорта"), то эти настройки так же следовало бы вписывать в эту текстовую команду?
Думаю, что это через системные переменные:
(https://live.staticflickr.com/65535/49837778716_db0c54ce48_o.png)

Есть ли документация на подобные lisp команды?
На какие команды?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 01-05-2020, 10:39:29
Есть ли документация на подобные lisp команды?
На какие команды?

Все, я разобрался. Вопрос снят. Спасибо!
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DFG2020 от 06-05-2020, 22:31:49
Всем добра!

Подскажите, как воспользоваться командой ВСТСПЕЦ через COM? Т.е. у меня есть скопированный диапазон ячеек в excel, как его вставить питоном в автокад, используя команду ВСТСПЕЦ/Объекты AutoCad?                  
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 06-05-2020, 22:38:57
Эту команду нельзя запустить в режиме командной строки.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DFG2020 от 06-05-2020, 22:42:03
Эту команду нельзя запустить в режиме командной строки.
Можно каким-то другим способом вставить таблицу эксел как объект автокад питоном?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 06-05-2020, 22:58:16
Если на Python можно прочитать excel-файл, то на основе его можно создать таблицу в AutoCAD. Подозреваю, что если это даже и возможно, то очень не просто.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 07-05-2020, 04:31:44
Если на Python можно прочитать excel-файл, то на основе его можно создать таблицу в AutoCAD. Подозреваю, что если это даже и возможно, то очень не просто.

Я так кстати и делал недавно. Питоновская библиотека openpyxl +  создание таблицы по полученным данным через COM.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DFG2020 от 08-05-2020, 18:03:23
Я так кстати и делал недавно.
Electric, прошу выслать данные наработки, если сохранились.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 08-05-2020, 20:57:51
Electric, прошу выслать данные наработки, если сохранились.

Минимальный пример без повтора объединения ячеек, считывания по диапазону и т.д.

Код - Python [Выбрать]
  1. from openpyxl import load_workbook
  2. import win32com.client
  3.  
  4. def readFromExcelFile(filename, page_name):
  5.     ''' Функция чтения Excel файла
  6.    filename - полный путь к файлу xlsx
  7.    page_name - название листа в документе    
  8.    '''
  9.     wb = load_workbook(filename, data_only=True)
  10.     sheet = wb[page_name]
  11.  
  12.     # Номер максимальной строки и столбца с данными на листе
  13.     row_count = sheet.max_row
  14.     column_count = sheet.max_column
  15.  
  16.     # Считывание текстовых данных по ячейкам, нумерация начинается c 1
  17.     data = [[sheet.cell(row=row_num, column=col_num).value for col_num in range(1, column_count+1)] for row_num in range(1, row_count+1)]
  18.     return data
  19.  
  20.  
  21. def writeAcadTable(data):
  22.     ''' Функция записи таблицы в Autocad '''
  23.  
  24.     app = win32com.client.Dispatch("AutoCAD.Application")    
  25.     aDoc = app.ActiveDocument
  26.     mSp = aDoc.ModelSpace
  27.  
  28.     # Число строк и столбцов в таблице
  29.     row_count = len(data)    
  30.     column_count = len(data[0])
  31.  
  32.     insertion_point = aDoc.Utility.GetPoint(convert_coordinates(0, 0, 0), 'Укажите точку вставки в пространстве  модели: ')
  33.     table = mSp.AddTable(convert_coordinates(insertion_point), row_count, column_count, 10, 30)
  34.     table.UnmergeCells(0, 0, 0, column_count-1)
  35.  
  36.     # Заполнение таблицы AutoCAD текстовыми данными
  37.     for i in range(row_count):        
  38.         for j in range(column_count):            
  39.             if data[i][j]:                
  40.                 table.SetText(i, j, data[i][j])
  41.  
  42. if __name__=='__main__':
  43.     data = readFromExcelFile('C:\\test.xlsx', 'Лист1')
  44.     writeAcadTable(data)
  45.  
  46.  

В этом примере в функции чтения  я использовал доступ к листу Excel по имени  листа. Если  требуется просто считать первый лист, например, то вместо строки 10 нужно:

Код - Python [Выбрать]
  1. sheet = wb.worksheets[0]

В функции записи writeAcadTable  функция "convert_coordinates" - взята из начала темы (https://adn-cis.org/forum/index.php?topic=7864.msg28996#msg28996).
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DFG2020 от 12-05-2020, 22:24:26
Electric, спасибо!!!
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 24-05-2020, 17:59:15
Заметил странное поведение при попытке установить выравнивание ячеек таблицы.
Есть таблица AutoCAD  5 строк, 4 столбца, выравнивание во всех ячейках  по умолчанию стоит "середина по центру".
Если я хочу назначить выравнивание "4" (середина влево) для строки с индексом "2" я пишу  "-1" в  качестве  индекса столбца:

Код - Python [Выбрать]
  1. table.SetCellAlignment(2, -1, 4)

и тогда по всей строке 2 выравнивание становится серединой влево.
Но если я пытаюсь применить подобный трюк с колонкой, а именно назначить всем ячейкам в  колонке с индексом 2 такое  выравнивание:

Код - Python [Выбрать]
  1. table.SetCellAlignment(-1, 2, 4)

у меня ничего не происходит. Что я делаю не так?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 24-05-2020, 19:35:56
у меня ничего не происходит. Что я делаю не так?
В принципе всё так. Проверил в AutoCAD 2021 - действительно целиком колонке выравнивание задать нельзя. Возможно причина как-то связана с разными типами данных в разных колонках (Title, Header, Data). Так что задавать выравнивание придётся в цикле всем ячейкам колонки.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 27-06-2020, 13:01:11
Коллеги, подскажите вот что,
построение чертежа занимает много времени. Можно ли как то на время приостановить отрисовку и после завешения построения обновить чертеж чтобы хоть как то ускорить процесс, по типу как это можно сделать с таблицей установив RegenerateTableSuppressed в False?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 27-06-2020, 13:58:42
Средствами COM/ActiveX приостановить отрисовку нельзя. Можно скрыть окно AutoCAD, а потом его сделать видимым. Но это вряд ли как-то ускорит построение чертежа. Кстати, обновление чертежа - это регенерация. И процесс регенерации может быть достаточно длительным.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Алексей Кулик от 06-07-2020, 08:31:08
Есть другой вариант: создать анонимный блок, все сделать внутри него, потом блок вставить, разбить и уничтожить вхождение блока.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DFG2020 от 08-07-2020, 18:49:11
Всем добра!

Такая задача: после конвертации из pdf на чертеже присутствует множество прямоугольных треугольников примерно одинаковой площади. Как их можно удалить одним махом, написав прогу в pythone? Треугольники состоят из полилинии. Можно как-то их всех найти по площади?

Спасибо!
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 08-07-2020, 19:43:13
Всем добра!

Такая задача: после конвертации из pdf на чертеже присутствует множество прямоугольных треугольников примерно одинаковой площади. Как их можно удалить одним махом, написав прогу в pythone? Треугольники состоят из полилинии. Можно как-то их всех найти по площади?

Спасибо!

Требуется просто удалить их, к примеру, через поиск?
Или нужно объединить их и заменить нормальными фигурами. Как если все прямые перевелись в виде состыкованных по гипотенузе прямоугольных треугольников.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DFG2020 от 08-07-2020, 21:57:30
Требуется просто удалить их, к примеру, через поиск?
Да, просто удалить.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 08-07-2020, 22:04:18
Можно как-то их всех найти по площади?
Нет. Да и вообще если бы это было можно, то способ был бы какой-то ненадежный. Нужно отобрать все полилинии (возможно на каком-то определенном слое), а затем уже обработать полученный набор:
1. Проверить, что у полилинии 3 вершины
2. Проверить, что они образуют прямоугольный треугольник
3. Проверить (возможно), что площадь в каких-то пределах
4. Проверить если есть еще какие-то критерии
Если все условия удовлетворяют, то удалить.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DFG2020 от 08-07-2020, 22:17:26
Если все условия удовлетворяют, то удалить.
Спасибо за ответ. Видимо проще вручную удалить.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 06-09-2020, 18:35:51
Мой скрипт считывает GetBoundingBox() нетекстовых объектов внутри блока, чтобы получить потом минимальную и максимальные точки всех нетекстовых объектов.  Координаты считываются сначала внутри блока, затем с учетом точки вставки, угла поворота и общего зеркалирования перевожу их в общие для чертежа.
Я заметил, что если объект отзеркален с помощью параметра "Отразить" внутри блока (не командой "отразить зеркально" с главной панели), его координаты GetBoundingBox() возвращаются точно такими же.  Я ошибаюсь или это так и должно быть?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Алексей Кулик от 06-09-2020, 20:35:18
Может, стоит обращаться к описанию не динамического блока, а к описанию именно этого анонимного? Т.е. вместо EffectiveName использовать простой Name?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 06-09-2020, 20:41:23
Координаты считываются сначала внутри блока, затем с учетом точки вставки, угла поворота и общего зеркалирования перевожу их в общие для чертежа.
Вот тут и вопрос. Внутри какого блока? Алексей Кулик правильно написал. Если работать с анонимным блоком, соответствующим текущему состоянию динамического блока, то никакие динамические параметры учитывать уже не нужно - они уже в этом анонимном блоке учтены. Плюс еще учтена и видимость примитивов внутри блока (см. у них свойство Visible).
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 07-09-2020, 05:19:21
Похоже, я плаваю в терминологии, я не знаком с понятием анонимного блока  :-\
У меня просто динамический блок.

У меня есть блок "Клемма_терминала", которую я создал. В ней атрибут "оттразить", который зеркалит ее по горизонтали. Обычно обращение к подобным блокам по EffectiveName проблем не вызывало, значение текстовых аттрибутов, координаты примитивов и прочее - считывалось без проблем.  Но вот считывание GetBoundingBox()  у  отраженного прямоугольника возвращает те же координаты, что и в исходном состоянии.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Алексей Кулик от 07-09-2020, 07:40:32
У вхождения динамического блока (файл не качал, некогда) есть его т.н. "эффективное имя" - которое отображается в панели свойств. А есть обычное имя - которое на самом деле не видно.
Если obj - указатель на вхождение блока, то посмотри, что вернет obj.Name и obj.EffectiveName. И проходить тебе надо именно по doc.Blocks(obj.Name)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 07-09-2020, 08:36:51
Спасибо! Наконец разобрался. Через obj.Name все работает,  не использовал его раньше.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: vxv от 09-09-2020, 09:43:44
Доброго времени суток, Всем кто читает это. Пишу внешнюю программу на Python 3.7 32-bit на виндовс 7. Сам новичок в этом деле и многое не понятно. Хочется систематизировать информацию, которой очень мало на данную тему в интернете. Для начала пытался создать все примитивы через библиотеку ezdxf. Все получилось, но результат меня не устроил. Все что было нарисовано, было сделано без открытия активной модели автокад и сохранено в файл *.dxf. Приходилось открывать этот файл и копировать с базовой точкой от туда в активный документ автокад, что само по себе рушило всю магию работы. Пытался как то это копировать в буфер без открытия, тоже ни чего не получилось. И в следствии решил изучить COM Autocad. На данном этапе остановился на штриховке, ее создании. На моменте задания внешних и внутренних границ все что я бы не делал терпит неудачу. Нашел следующий код на IronPython:

Код - Python [Выбрать]
  1. # Load the Python Standard and DesignScript Libraries
  2. import sys, clr, System
  3. clr.AddReference('ProtoGeometry')
  4. from Autodesk.DesignScript.Geometry import *
  5. from math import tan, radians
  6. from System import Array
  7. # Create Hatch
  8. outerLoop=Array.CreateInstance(AcadEntity,1)
  9. outerLoop[0] = allPoly[0]
  10. innerLoop=Array.CreateInstance(AcadEntity,1)
  11. innerLoop[0] = allPoly[1]
  12. hatchObj = SPACE.AddHatch(0, "ANSI31", True)
  13. hatchObj.AppendOuterLoop(outerLoop)
  14. hatchObj.AppendInnerLoop(innerLoop)
  15. hatchObj.Evaluate()
  16. hatchObj.PatternScale = 1
  17. CAD.Application.Update()
  18. # Assign your output to the OUT variable.
  19. OUT = allPoly, innerLoop

Похожий вопрос был от пользователя  Khasan Mamaev « Ответ #12 : 13-11-2017, 12:14:55 »:
Код - Python [Выбрать]
  1. def plineToRegion(pl):
  2.         entArr = Array.CreateInstance(AcadEntity,1)
  3.         entArr.SetValue(pl,0)
  4.         return msp.AddRegion(entArr)  

Решение было от dlobyntsev « Ответ #13 : 13-11-2017, 16:26:50 »:

Код - Python [Выбрать]
  1. def plineToRegion(pl):
  2.     msp.AddRegion(win32com.client.VARIANT(VT_ARRAY | VT_DISPATCH, [pl]))

Но не пойму как это запустить.
Помогите создать штриховку с указанием внешних и внутренних границ пожалуйста???
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 11-09-2020, 19:00:50
Если нужно создать именно region, т.е. область, то это так  на COM:

Код - Python [Выбрать]
  1. import win32com.client
  2. from pythoncom import VT_ARRAY, VT_R8, VT_DISPATCH
  3.  
  4. def cc(*args):
  5.     '''
  6.    Функция преобразования координат в формат AutoCAD
  7.    :param args: координаты для преобразования, допустима передача списка или кортежа
  8.    :return: Координаты в формате AutoCAD
  9.    '''
  10.     if isinstance(args[0], (list, tuple)):
  11.         coords = [item for item in args[0]]
  12.     else:
  13.         coords = args
  14.     return win32com.client.VARIANT(VT_ARRAY | VT_R8, coords)
  15.  
  16. if __name__=='__main__':
  17.  
  18.     # Доступ к пространству модели
  19.     app = win32com.client.Dispatch("AutoCAD.Application")
  20.     aDoc = app.ActiveDocument
  21.     mSp = aDoc.ModelSpace
  22.  
  23.     # Добавим  два круга, к примеру. Первый аргумент - координата центра, второй - радиус
  24.     circle1 = mSp.AddCircle(cc(0,0,0), 10)
  25.     circle2 = mSp.AddCircle(cc(50,50,0), 20)
  26.  
  27.     # преобразуем  круги в "области"
  28.     region1 = mSp.AddRegion(win32com.client.VARIANT(VT_ARRAY | VT_DISPATCH, [circle1, circle2]))


Но это область, это не штриховка. Только сейчас  поймал себя на мысли, что никогда не использовал этот объект в своей  работе, видимо, электрикам он не пригождается.
Если надо создать штриховку, то должно быть как-то так:

Код - Python [Выбрать]
  1. hatch1 = mSp.AddHatch(PatternType = 1,
  2.                          PatternName = "ANSI31",
  3.                         Associativity = True,
  4.                         HatchObjectType = 1)
  5.  
  6. hatch1.AppendOuterLoop(win32com.client.VARIANT(VT_ARRAY | VT_DISPATCH, [circle1, circle2]))

Но лично у меня при попытке назначить такую штриховку вылетает ошибка:

Цитировать
hatch1 = mSp.AddHatch(PatternType = 1,
  File "C:\Users\2E78~1\AppData\Local\Temp\gen_py\3.8\E2077CF2-3573-4E66-B1DC-01118675056Dx0x1x0\IAcadModelSpace.py", line 254, in AddHatch
    ret = self._oleobj_.InvokeTypes(1579, LCID, 1, (9, 0), ((3, 1), (8, 1), (11, 1), (12, 17)),PatternType
pywintypes.com_error: (-2147352567, 'Ошибка.', (0, 'AutoCAD.Application', 'Пока не реализовано', 'C:\\Program Files\\Autodesk\\AutoCAD 2020\\HELP\\OLE_ERR.CHM', -2145386495, -2145386495), None)

Пока нереализовано...
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 11-09-2020, 19:33:57
Но лично у меня при попытке назначить такую штриховку вылетает ошибка:

Цитировать

    hatch1 = mSp.AddHatch(PatternType = 1,
      File "C:\Users\2E78~1\AppData\Local\Temp\gen_py\3.8\E2077CF2-3573-4E66-B1DC-01118675056Dx0x1x0\IAcadModelSpace.py", line 254, in AddHatch
        ret = self._oleobj_.InvokeTypes(1579, LCID, 1, (9, 0), ((3, 1), (8, 1), (11, 1), (12, 17)),PatternType
    pywintypes.com_error: (-2147352567, 'Ошибка.', (0, 'AutoCAD.Application', 'Пока не реализовано', 'C:\\Program Files\\Autodesk\\AutoCAD 2020\\HELP\\OLE_ERR.CHM', -2145386495, -2145386495), None)


Пока нереализовано...
Так и должно быть. Каждый из контуров - это один замкнутый контур. А у тебя две окружности. Т.е. одна должна быть внутренним контуром, а вторая наружным.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 11-09-2020, 19:38:42
Где-то наверное так:
Код - Python [Выбрать]
  1. circle1 = mSp.AddCircle(cc(0,0,0), 100)
  2. circle2 = mSp.AddCircle(cc(20,20,0), 30)
  3. hatch1 = mSp.AddHatch(PatternType = 0,
  4.      PatternName = "ANSI31",
  5.      Associativity = True,
  6.      HatchObjectType = 0)
  7. hatch1.AppendOuterLoop(win32com.client.VARIANT(VT_ARRAY | VT_DISPATCH, [circle1]))
  8. hatch1.AppendInnerLoop(win32com.client.VARIANT(VT_ARRAY | VT_DISPATCH, [circle2]))
  9. hatch1.Evaluate()

Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 11-09-2020, 20:53:59
Но лично у меня при попытке назначить такую штриховку вылетает ошибка:

Цитировать

    hatch1 = mSp.AddHatch(PatternType = 1,
      File "C:\Users\2E78~1\AppData\Local\Temp\gen_py\3.8\E2077CF2-3573-4E66-B1DC-01118675056Dx0x1x0\IAcadModelSpace.py", line 254, in AddHatch
        ret = self._oleobj_.InvokeTypes(1579, LCID, 1, (9, 0), ((3, 1), (8, 1), (11, 1), (12, 17)),PatternType
    pywintypes.com_error: (-2147352567, 'Ошибка.', (0, 'AutoCAD.Application', 'Пока не реализовано', 'C:\\Program Files\\Autodesk\\AutoCAD 2020\\HELP\\OLE_ERR.CHM', -2145386495, -2145386495), None)


Пока нереализовано...
Это из-за PatternType = 1. Должно быть PatternType = 0.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: vxv от 12-09-2020, 06:41:37
circle1 = mSp.AddCircle(cc(0,0,0), 100)
circle2 = mSp.AddCircle(cc(20,20,0), 30)
hatch1 = mSp.AddHatch(PatternType = 0,
     PatternName = "ANSI31",
     Associativity = True,
     HatchObjectType = 0)
hatch1.AppendOuterLoop(win32com.client.VARIANT(VT_ARRAY | VT_DISPATCH, [circle1]))
hatch1.AppendInnerLoop(win32com.client.VARIANT(VT_ARRAY | VT_DISPATCH, [circle2]))
hatch1.Evaluate()

Кстате работает и без строчки:
Код - Python [Выбрать]
  1. hatch1.Evaluate()

Большое спасибо за помощь. я был очень близко к разгадке, ходил кругами. и уже даже отчаялся. Вы меня спасли!!!!!!!!
Хочу выслать ссылку с репозиторем. В нем очень грамотно прописаны все другие моменты по Автокаду для тех кто как я только начинает в этой области творить:
https://github.com/JohnYang1210/PycomCAD
 :) :) :) :) :) :) :)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: vxv от 12-09-2020, 09:56:15
Комплект чертежей состоит из нескольких листов. Мы их обрамляем рамками, у которых есть свой штамп и другое. Эти листы мы располагаем в пространстве модели друг за другом. И на каждом из них может присутствовать какой-то элемент в определенном месте относительно глобальных координат. Можно конечно каждый раз переносить начало координат в нужную нам точку пространства, но думаю есть проектировщики, для кого это критично и недопустипо, да и выглядеть это будет не совсем удобно.
Внимание, а теперь вопрос к знатокам: "Как перед выполнением скрипта отправить запрос в Autocad об указании точки вставки результатов действий скрипта???" Другими словами - указать начало координат для скрипта не (0,0,0), а место куда укажем мышкой. Либо координаты того или иного элемента, который мы выделим мышкой. Думаю такая тема будет много кому полезна. Заранее спасибо и хорошего настроения всем...
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 12-09-2020, 12:10:27
Комплект чертежей состоит из нескольких листов. Мы их обрамляем рамками, у которых есть свой штамп и другое. Эти листы мы располагаем в пространстве модели друг за другом. И на каждом из них может присутствовать какой-то элемент в определенном месте относительно глобальных координат. Можно конечно каждый раз переносить начало координат в нужную нам точку пространства, но думаю есть проектировщики, для кого это критично и недопустипо, да и выглядеть это будет не совсем удобно.

Нужно найти и прочитать этот элемент по сдвигу относительно края рамки? номер страницы к примеру.

Цитата: vxv
Внимание, а теперь вопрос к знатокам: "Как перед выполнением скрипта отправить запрос в Autocad об указании точки вставки результатов действий скрипта???" Другими словами - указать начало координат для скрипта не (0,0,0), а место куда укажем мышкой. Либо координаты того или иного элемента, который мы выделим мышкой. Думаю такая тема будет много кому полезна. Заранее спасибо и хорошего настроения всем...

В начале темы где-то было:

Код - Python [Выбрать]
  1. point = aDoc.Utility.GetPoint(cc(0, 0, 0), "Укажите точку вставки:")
Название: Re: Python & ActiveX/COM Autocad
Отправлено: vxv от 12-09-2020, 16:24:01
Electric, щас доберусь до компа попробую эту строчку. Просто пока не забыл хочу поздравить всех с днём програмиста. Ееееехххххууууу ;D ;D ;D ;D
Название: Re: Python & ActiveX/COM Autocad
Отправлено: vxv от 12-09-2020, 16:53:50
Electric, эта строчка то что нужно, работает на ура. Спасибо большое.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 12-10-2020, 06:52:36
Огромная просьба, кто знает, подскажите.

Написано большое количество скриптов на питоне для AutoCad. Внезапно Автокад начал глючить вот в каком плане: при обращении к COM функциям они очень часто стали заканчиваться с ошибкой "Вызов был отклонен". Раньше такое в основном случалось, если во время работы скрипта введешь команду или ткнешь мышкой в чертеж, ну и очень редко, по другим причинам типа автосохранения или еще чего то, но это еще чего то было настолько редким, что в принципе можно было не обращать внимания. Сейчас же такое происходит через раз. Скрипты становятся неработоспособными, потому что вызовов много и если на каком то из них прерывается, то весь скрипт надо перезапускать,  или еще хуже, убирать то что наделал незаконченный скрипт.
В общем проблема серьезная. Понимаю, что можно перед каждым вызовом функции делать проверки, но это не выход: во первых такая ерунда может произойти даже при обращении к свойствам объекта, а каждую такую строчку проверять - как бы уже бредом попахивает.
В общем есть ли у кого мысли что могло произойти с автокадом? Как это можно попробовать исправить? Простую переустановку я сделал, не помогло...
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 12-10-2020, 10:44:02
Понимаю, что можно перед каждым вызовом функции делать проверки, но это не выход: во первых такая ерунда может произойти даже при обращении к свойствам объекта, а каждую такую строчку проверять - как бы уже бредом попахивает.
Это единственный выход при использовании COM. Причем между обращениями к AutoCAD следует делать задержку как минимум в 500 миллисекунд.
Так это выглядит на C++: https://adn-cis.org/kak-ispolzuya-visual-c-zapustit-autocad-i-zastavit-ego-vyipolnyat-nekotoryie-dejstviya.html
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 12-10-2020, 12:23:04
Скажем там, несколько дней назад такой проблемы не было точно... Все работало нормально.
Во вторых - проблема то возникает не только при вызове функции, но даже при обращении к свойствам объектов... Ведь каждый раз делать проверки даже при обращении к свойствам - очень сомнительно что это вообще имеет смысл... Скрипты вроде придумали чтобы упрощать жизнь и исключить работу которую можно поручить компьютеру. В таком случае код превращается в проверки проверок перед проверками перед тем как проверить удачно ли прошло обращение к функции или к объекту.

Опять же, раньше то работало и меня все устраивало.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 12-10-2020, 12:29:57
Опять же, раньше то работало и меня все устраивало.
Если раньше всё работало и AutoCAD не обновлял, то вероятно обновилась Windows. Но вообще-то просто тебе раньше везло. Такая проблема известна как минимум 10 лет. И именно поэтому я не рекомендую использовать COM/ActiveX, а писать приложения, которые грузятся внутрь AutoCAD.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 12-10-2020, 12:33:28
Если только все обращения к свойствам объектов обернуть в:

Код - Python [Выбрать]
  1. while True:
  2.     try:
  3.         #операции считывания свойств у объектов AutoCAD
  4.     except:
  5.         pass
  6.     else:
  7.         break.

Но с графическими построениями такое не прокатит.
Похоже, что кроме изучения C# от такого не избавиться.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 12-10-2020, 12:35:40
Если только все обращения к свойствам объектов обернуть в:
Не хватает задержки перед очередным обращением в случае except.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 12-10-2020, 12:40:17
Ну да, тогда импортировать time и  задавать выдержку с помощью time.sleep(0.5). И цикл делать не вечный.
У меня тоже скрипты с COM работают как повезет, приходится обрабатывать такие ошибки.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DMuzer от 12-10-2020, 15:20:16
Ну что же, спасибо за ответы... Видимо, я везучий)))
Жаль что такая засада с COM вылезает.
Как то я привык python как почти замену командной строки автокада использовать. Учитывая наличие массы библиотек, расчетов
можно делать вещи, которые изнутри автокада недоступны именно потому, что перед загрузкой внутрь автокада приложение нужно написать, отладить, откомпилировать...
А через COM - практически появилась мысль - сразу попробовал, потестировал, извлек инфо из чертежа, обработал, расчитал и обратно построил... На C# это думаю, недоступно просто потому что усилий и времени потребуется в сотни раз больше.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: AndONE от 05-11-2020, 14:06:30
Добрый день.
Хочу автоматизировать процесс через python + com.
Мне нужно в текущем чертеже к выборке применять "BURST"
Но дело в том, что этого метода в com модели нет. Я планирую использовать sendcommand, но не понимаю, как мне передать туда требуемый массив объектов? Подскажите?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Алексей Кулик от 05-11-2020, 14:22:24
burst - отдельная команда, входящая в состав ExpressTools (если не ошибаюсь).
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 05-11-2020, 15:03:49
AndONE,
IMHO - это извращение. Для того, чтобы проделать эту процедуру, тебе придётся ко всему прочему еще и использовать Lisp, так как через COM-модель нельзя передать объекты в командную строку.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: AndONE от 05-11-2020, 15:10:08
AndONE,
IMHO - это извращение. Для того, чтобы проделать эту процедуру, тебе придётся ко всему прочему еще и использовать Lisp, так как через COM-модель нельзя передать объекты в командную строку.
Подскажите тогда через Python нормальный способ?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 05-11-2020, 15:16:29
Подскажите тогда через Python нормальный способ?
Через Python в принципе не может быть нормального способа - это не поддерживаемый с точки зрения AutoCAD язык программирования. И кроме того COM/ActiveX интерфейс AutoCAD уже очень сильно устарел и не позволяет то, что легко делается при помощи (например) AutoCAD .NET API. Фактически тебе потребуется переписать BURST на Python.

Название: Re: Python & ActiveX/COM Autocad
Отправлено: AndONE от 05-11-2020, 15:22:34
В общем-то я так и думал. Дело в том, что основной язык на котором разрабатывается приложение выбран именно Python.
И COM модели полностью хватает для закладыавемого функционала, за исключением этой функции (BURST).
Подскажите пжл, даже если это и извращение. Какую команду в LISP гуглить, чтобы передать объекты через sendcommand?
У меня будет на входе либо selectionset либо массив объектов, к которым надо применить BURTS.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 05-11-2020, 15:27:22
Какую команду в LISP гуглить, чтобы передать объекты через sendcommand?
В lisp нет команд - одни функции. В данном случае тебе придётся в командную строку передать метки (Handle) всех объектов с вызовом функции (handent "метка"). Если объектов будет много, то через командную строку ты их передать не сможешь.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: AndONE от 05-11-2020, 15:30:14
Какую команду в LISP гуглить, чтобы передать объекты через sendcommand?
В lisp нет команд - одни функции. В данном случае тебе придётся в командную строку передать метки (Handle) всех объектов с вызовом функции (handent "метка"). Если объектов будет много, то через командную строку ты их передать не сможешь.
окей, спасибо.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 05-11-2020, 15:34:24
Я посмотрел исходники BURST (он действительно в Express Tools). Можно сильно упростить себе жизнь если воспользоваться оттуда функцией (BURST-ONE) - она выполняет BURST по одному объекту за раз. Поэтому можно выполнить в цикле строку при помощи Sendcommand:
"(burst-one (handent \"здесь метка примитива\")) "
Надеюсь, что это даст результат.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: AndONE от 05-11-2020, 15:48:23
Я посмотрел исходники BURST (он действительно в Express Tools). Можно сильно упростить себе жизнь если воспользоваться оттуда функцией (BURST-ONE) - она выполняет BURST по одному объекту за раз. Поэтому можно выполнить в цикле строку при помощи Sendcommand:
"(burst-one (handent \"здесь метка примитива\")) "
Надеюсь, что это даст результат.
Это просто шикарно!
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 23-12-2020, 18:41:17
Возможно ли через COM использовать зависимости со вкладки "Параметризация"?  или это тоже недоступная для ActiveX возможность?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 23-12-2020, 20:31:22
Возможно ли через COM использовать зависимости со вкладки "Параметризация"?  или это тоже недоступная для ActiveX возможность?
Увы, нет. И даже в .NET с этим совсем не просто, а более-менее доступно только в ObjectARX.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 24-12-2020, 19:38:29
Для эксперимента, скачал и установил ObjectARX последней версии, установил питоновскую библиотеку pythonnet. Переделал найденный в интернете кусок кода.

Код - Python [Выбрать]
  1. import sys
  2. path = u'F:\\ObjectARX\\ObjectARX_for_AutoCAD_2021_Win_64bit_dlm\\inc\\'
  3. #path to the .NET assemblies
  4. sys.path.append(path)
  5.  
  6. import clr
  7.  
  8. from System.Reflection import Assembly
  9. Assembly.LoadFrom(path + 'AcDbMgd.dll')
  10. Assembly.LoadFrom(path + 'AcCoreMgd.dll')
  11. Assembly.LoadFrom(path + 'AcMgd.dll')
  12.  
  13. import Autodesk
  14. import Autodesk.AutoCAD.DatabaseServices as ads
  15. import Autodesk.AutoCAD.Runtime as ar
  16. import Autodesk.AutoCAD.ApplicationServices as aas
  17. import Autodesk.AutoCAD.DatabaseServices as ads
  18. import Autodesk.AutoCAD.Geometry as ag
  19. import Autodesk.AutoCAD.Internal as ai
  20. from Autodesk.AutoCAD.Internal import Utils
  21.  
  22. print('Hello world!')

Пока ошибок не выдает, "Hello World!" в конце выводит... В какую сторону дальше копать? Хотя бы что бы получить активный  документ и нарисовать отрезок в Автокаде таким  образом.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 24-12-2020, 20:25:28
Electric,
Если она не грузится внутрь AutoCAD, то ты ничего не сделаешь. Все эти сборки можно использовать только в плагине, загруженном внутрь AutoCAD.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 25-12-2020, 07:12:48
Если она не грузится внутрь AutoCAD, то ты ничего не сделаешь. Все эти сборки можно использовать только в плагине, загруженном внутрь AutoCAD.

Я рассчитывал на возможность изучить ObjectARX взаимодействуя с помощью обычного пайтона, без применения сложных Си-подобных языков или атавизмов вроде IronPython.
Если я все правильно понимаю, этот вариант недоступен в принципе, то значит только C++/C#. только хардкор  8)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 25-12-2020, 13:56:27
Electric,
Чтобы изучить ObjectARX нужно изучать ObjectARX. Python тут может только мешать.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DFG2020 от 25-01-2021, 00:38:24
Всем добра!

Прошу ответить на такой вопрос: С++ открывает больше возможностей для использования автокада или питон покрывает все возможные расширения использования? Проще: какой язык заметно лучше позволит использовать автокад, С++ или питон? Или этот вопрос не корректен и все зависит от уровня владения языком?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 25-01-2021, 00:43:54
DFG2020,
ObjectARX C++ даёт на порядок больше возможностей. Про быстродействие я вообще молчу...
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 25-01-2021, 07:26:35
А если сравнивать .NET и ObjectARX - то по скорости работы и по  своим возможностям первый вариант не сильно уступает второму? Мне не требуется создавать свои объекты в AutoCAD и как мне кажется, C# легче в освоении, там нет необходимости работать с ссылками и указателями. Или я снова ошибаюсь?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 25-01-2021, 09:49:40
А если сравнивать .NET и ObjectARX - то по скорости работы и по  своим возможностям первый вариант не сильно уступает второму?
Не сильно если используется AutoCAD .NET API, а не COM/ActiveX
Мне не требуется создавать свои объекты в AutoCAD и как мне кажется, C# легче в освоении, там нет необходимости работать с ссылками и указателями. Или я снова ошибаюсь?
Не ошибаешься.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: DFG2020 от 25-01-2021, 12:56:57
DFG2020,
ObjectARX C++ даёт на порядок больше возможностей. Про быстродействие я вообще молчу...

Александр, спасибо за ответ! Начинаю изучать С++!
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Lemieux от 02-02-2021, 13:56:11
После опыта MEL/Python, когда работал в Maya, и написания САПРа на AutoLISP для AutoCAD, стал осваивать C# и мне он очень понравился, так как открывает возможность написания плагинов не только для AutoCAD, но и различных приложений, в том числе для мобильной платформы. C# стал изучать из-за невозможности на DCL(AutoLISP) писать нормальные интерфейсы.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: loban_iv от 18-02-2021, 16:41:31
Добрый день
возможно ли с помощью Python осуществить выдавливание области?
документация по ActiveX говорит что это возможно

RetVal = object.AddExtrudedSolid(Profile, Height, TaperAngle)

Получаю ошибку TypeError: The Python instance can not be converted to a COM object
я так понимаю ошибка в передаче объекта Python в Profile


Код - Python [Выбрать]
  1. import win32com
  2. import win32com.client
  3. from pythoncom import VT_R8, VT_ARRAY, VT_DISPATCH, VT_VARIANT
  4.  
  5. def convert_coordinates(*args):
  6.     """
  7.    Функция преобразования координат в формат AutoCAD
  8.    :param args: координаты для преобразования, допустима передача списка или кортежа
  9.    :return: Координаты в формате AutoCAD
  10.    """
  11.     if isinstance(args[0], (list, tuple)):
  12.         coords = [item for item in args[0]]
  13.     else:
  14.         coords = args
  15.     return win32com.client.VARIANT(VT_ARRAY | VT_R8, coords)
  16.  
  17. app = win32com.client.Dispatch("AutoCAD.Application")
  18. doc = app.ActiveDocument
  19. model = doc.ModelSpace
  20.  
  21. cds = convert_coordinates([0,0,0])
  22. c = model.AddCircle(cds,500)
  23. reg = model.AddRegion(win32com.client.VARIANT(VT_ARRAY | VT_DISPATCH, [c]))
  24. exsol1 = model.AddExtrudedSolid(reg, 100, 2)# TypeError: The Python instance can not be converted to a COM object
  25.  

Спасибо
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 18-02-2021, 16:53:42
reg = model.AddRegion(win32com.client.VARIANT(VT_ARRAY | VT_DISPATCH, [c]))
reg - это не один Region, а коллекция. Так что нужно использовать элемент с нулевым индексом.
Ну и кроме того угол в радианах, так что 2 - это 114.591559 градусов. Подозреваю, что ты хотел не это.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: loban_iv от 18-02-2021, 17:01:48
reg - это не один Region, а коллекция. Так что нужно использовать элемент с нулевым индексом.
Ну и кроме того угол в радианах, так что 2 - это 114.591559 градусов. Подозреваю, что ты хотел не это.

Спасибо! да конечно
все работает
Код - Python [Выбрать]
  1. exsol1 = model.AddExtrudedSolid(reg[0], 100, 0)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: loban_iv от 18-02-2021, 23:52:16
И еще вопрос если можно
Пытаюсь выполнить команду Loft с помощью Питона. В документации к  ActiveX говориться что это не поддерживается.
Пытаюсь создать 2 окружности, выбрать их, и послать в командную строку команду Loft
Но объекты не выбираются. Реально воплотить задуманное?
спасибо

Код - Python [Выбрать]
  1. import win32com
  2. import win32com.client
  3. from pythoncom import VT_R8, VT_ARRAY, VT_DISPATCH, VT_VARIANT
  4.  
  5. def convert_coordinates(*args):
  6.         """
  7.         Функция преобразования координат в формат AutoCAD
  8.         :param args: координаты для преобразования, допустима передача списка или кортежа
  9.         :return: Координаты в формате AutoCAD
  10.         """
  11.         if isinstance(args[0], (list, tuple)):
  12.                 coords = [item for item in args[0]]
  13.         else:
  14.                 coords = args
  15.         return win32com.client.VARIANT(VT_ARRAY | VT_R8, coords)
  16.  
  17.  
  18. app = win32com.client.Dispatch("AutoCAD.Application")
  19. doc = app.ActiveDocument
  20. model = doc.ModelSpace
  21.  
  22. cds = convert_coordinates([0, 0, 0])
  23. c = model.AddCircle(cds, 500)
  24. cds = convert_coordinates([0, 0, 200])
  25. c1 = model.AddCircle(cds, 250)
  26.  
  27. doc.SelectionSets.Item("MySelectionSet").Delete()
  28. ss = doc.SelectionSets.Add("MySelectionSet")
  29.  
  30. ss.AddItems(win32com.client.VARIANT(VT_ARRAY | VT_DISPATCH, [c, c1]))
  31. ss.Update()
  32. doc.SendCommand("_Loft\n\n")
Название: Re: Python & ActiveX/COM Autocad
Отправлено: loban_iv от 19-02-2021, 08:43:29
И еще не могу трансформировать объект((
например точку
это возможно?
Код - Python [Выбрать]
  1. app = win32com.client.Dispatch("AutoCAD.Application")
  2. doc = app.ActiveDocument
  3. model = doc.ModelSpace
  4.  
  5. origin = convert_coordinates([200, 0, 0])
  6. xaxis = convert_coordinates([201, 0, 0])
  7. yaxis = convert_coordinates([200, 1, 0])
  8.  
  9. ucs = doc.UserCoordinateSystems.Add(origin, xaxis, yaxis, "TestUCS")
  10. doc.ActiveUCS = ucs
  11. m4x4 = ucs.GetUCSMatrix()
  12.  
  13. cds = convert_coordinates([0, 0, 0])
  14. p1 = model.AddPoint(cds)
  15. p1.TransformBy(m4x4)
  16. # Traceback (most recent call last):
  17. #   File "C:/Users/lobanov/PycharmProjects/AutoCAD_proj/main.py", line 34, in <module>
  18. #     p1.TransformBy(m4x4)
  19. #   File "<COMObject AddPoint>", line 2, in TransformBy
  20. # pywintypes.com_error: (-2147352567, 'Exception occurred.', (0, None, None, None, 0, -2147024809), None)

Спасибо!
А может есть какое то более элегантное решение касательно трансформации?
мне нужно будет строить геометрию в разных системах координат. Я думал что создав временную ПСК и активируя ее,  далее в коде используя координаты они будут трансформироваться относительно активной ПСК. Вроде бы я не прав и все объекты продолжают строится относительно глобальной системы координат. Это так?или есть какая нибудь переменная - переключатель - от чего  считать координаты?Если нет, мое решение - трансформировать все объекты матрицей 4х4?

Название: Re: Python & ActiveX/COM Autocad
Отправлено: loban_iv от 19-02-2021, 13:15:28
Loft решил добавлением временных групп. Наверно несколько топорно
Может можно было через SelectSet?и смущают кириллические буквы в тексте вызываемой команды
Нет какой нибудь установки чтоб Autocad понимал латинские буквы для дополнения команд?
Код - Python [Выбрать]
  1. app = win32com.client.Dispatch("AutoCAD.Application")
  2. doc = app.ActiveDocument
  3. model = doc.ModelSpace
  4.  
  5. cds = convert_coordinates([0, 0, 0])
  6. c = model.AddCircle(cds, 500)
  7. cds = convert_coordinates([0, 0, 300])
  8. c1 = model.AddCircle(cds, 250)
  9.  
  10. g = doc.Groups.Add("1")
  11. g1 = doc.Groups.Add("2")
  12.  
  13. g.AppendItems(win32com.client.VARIANT(VT_ARRAY | VT_DISPATCH, [c]))
  14. g1.AppendItems(win32com.client.VARIANT(VT_ARRAY | VT_DISPATCH, [c1]))
  15.  
  16. doc.SendCommand("_LOFT Г " + g.Name + "\n" + "Г " + g1.Name + "\n" + "Ж" + "\n" + "Т" + "\n\n\n")
  17.  
  18. g.Delete()
  19. g1.Delete()
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 19-02-2021, 16:11:12
Нет какой нибудь установки чтоб Autocad понимал латинские буквы для дополнения команд?

Это не дополнительные команды, а опции команд. И можно (так же, как и для команд) использовать их глобальные имена - английские с подчеркиванием спереди.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 19-02-2021, 16:12:27
Вроде бы я не прав и все объекты продолжают строится относительно глобальной системы координат. Это так?
Да.
Если нет, мое решение - трансформировать все объекты матрицей 4х4?
Да.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: loban_iv от 19-02-2021, 21:05:41
Александр, а нет мыслей по поводу как передать матрицу4х4 в TransformBy?
4х компонентный массив 4х компонентных массивов
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 19-02-2021, 21:20:12
loban_iv,
Как в Python - понятия не имею. На VBA есть пример в документации. Вообще же эта матрица должна быть VARIANT.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 19-02-2021, 21:33:58
Подозреваю, что через Utility.CreateTypedArray(matrix, vbDouble, [16 плавающих чисел, образующих матрицу 4x4])
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Marik от 15-06-2021, 00:48:31
Господа, подскажите! Читал, читал тему...в голове каша. Подскажите как начертить полилинию? Можно код? Что нужно вставить в AddLightweightPolyline?

Код:
Код - Python [Выбрать]
  1. import win32com.client
  2. from pythoncom import  VT_R8, VT_ARRAY, VT_DISPATCH, VT_VARIANT
  3.  
  4. appAutocad = win32com.client.GetActiveObject("AutoCAD.Application")
  5. aDoc = appAutocad.ActiveDocument
  6. mSp = aDoc.ModelSpace
  7.  
  8. def acadcoord(x,y,z): # преобразование координат
  9.     return win32com.client.VARIANT(VT_ARRAY | VT_R8, [x, y, z])
  10.  
  11. mSp.AddLightweightPolyline(??????)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 15-06-2021, 08:19:12
Господа, подскажите! Читал, читал тему...в голове каша. Подскажите как начертить полилинию? Можно код? Что нужно вставить в AddLightweightPolyline?

Код:
Код - Python [Выбрать]
  1. import win32com.client
  2. from pythoncom import  VT_R8, VT_ARRAY, VT_DISPATCH, VT_VARIANT
  3.  
  4. appAutocad = win32com.client.GetActiveObject("AutoCAD.Application")
  5. aDoc = appAutocad.ActiveDocument
  6. mSp = aDoc.ModelSpace
  7.  
  8. def acadcoord(x,y,z): # преобразование координат
  9.     return win32com.client.VARIANT(VT_ARRAY | VT_R8, [x, y, z])
  10.  
  11. mSp.AddLightweightPolyline(??????)

Примерно так:

Код - Python [Выбрать]
  1. import win32com.client
  2. from pythoncom import  VT_R8, VT_ARRAY, VT_DISPATCH, VT_VARIANT
  3.  
  4. appAutocad = win32com.client.GetActiveObject("AutoCAD.Application")
  5. aDoc = appAutocad.ActiveDocument
  6. mSp = aDoc.ModelSpace
  7.  
  8. def acadcoord(*args): # преобразование координат
  9.     if isinstance(args[0], (list, tuple)):
  10.         coords = [item for item in args[0]]
  11.     else:
  12.         coords = args
  13.     return win32com.client.VARIANT(VT_ARRAY | VT_R8, coords)
  14.  
  15.  
  16. line_coords = [0, 0, 300, 100]  # В списке или в кортеже передаешь координаты точек x, y вершин полилинии
  17.  
  18. if __name__=='__main__':
  19.     mSp.AddLightweightPolyline(acadcoord(line_coords))
  20.  
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Marik от 15-06-2021, 09:27:56
Спасибо! Работает!
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Aleks_199513 от 08-07-2021, 09:33:21
Добрый день. Подскажите как вставить блок в таблицу? пробовал метод tab.SetBlockTableRecordId2(1,1,1928560679024,True) выдает ошибку. И как можно найти ID блока? ObjectID не срабатывает
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 08-07-2021, 12:09:52
И как можно найти ID блока? ObjectID не срабатывает
Что значит не срабатывает?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Aleks_199513 от 08-07-2021, 14:53:14
И как можно найти ID блока? ObjectID не срабатывает
Что значит не срабатывает?
Пишет, что у объекта нет ID.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 08-07-2021, 15:03:01
Пишет, что у объекта нет ID.
Покажи код и сообщение об ошибке.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Aleks_199513 от 08-07-2021, 15:20:36
Пишет, что у объекта нет ID.
Покажи код и сообщение об ошибке.
Код - Python [Выбрать]
  1. import clr
  2. import System
  3. from System import Array
  4. # Add Assemblies for AutoCAD and Civil3D
  5. clr.AddReference('AcMgd')
  6. clr.AddReference('AcCoreMgd')
  7. clr.AddReference('AcDbMgd')
  8. clr.AddReference('AecBaseMgd')
  9. clr.AddReference('AecPropDataMgd')
  10. clr.AddReference('AeccDbMgd')
  11. import Autodesk
  12.  
  13.  
  14.  
  15. app = System.Runtime.InteropServices.Marshal.GetActiveObject("Autocad.Application.24")
  16. aDoc = app.ActiveDocument
  17. mSp = aDoc.PaperSpace
  18.  
  19.  
  20. tname = IN[0]
  21. bb = IN[1]
  22.  
  23. tab = None
  24. for i in mSp:
  25.         if i.EntityName == 'AcDbTable':
  26.                 if i.GetCellValue(0, 0) == tname:
  27.                         tab = i
  28.  
  29. lenght = 1
  30. r= bb.ObjectID
  31.  
  32. #k=tab.SetBlockTableRecordId(1,1,1928560679024,True)
  33. OUT = r
(https://i.postimg.cc/9wt8zx3W/image.jpg) (https://postimg.cc/9wt8zx3W)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 08-07-2021, 15:25:56
Что в IN[0] и в IN[1]? То что у Block есть свойство ObjectID - это 100%.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 08-07-2021, 15:32:37
Стоп. Я что-то не понял откуда запускается Python? Перечисленные сборки можно использовать только в приложении, загруженном внутрь AutoCAD, но нельзя использовать во внешнем приложении, обращающемся к AutoCAD через COM/ActiveX.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Aleks_199513 от 08-07-2021, 15:38:47
Что в IN[0] и в IN[1]? То что у Block есть свойство ObjectID - это 100%.
(https://i.postimg.cc/nj0zGxfg/12.jpg) (https://postimg.cc/nj0zGxfg)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 08-07-2021, 15:41:20
Aleks_199513,
Это мне ничего не говорит.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Aleks_199513 от 08-07-2021, 15:42:24
Aleks_199513,
Это мне ничего не говорит.
В IN[0] имя таблицы идет, в IN[1] блок
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 08-07-2021, 15:45:07
Aleks_199513,
Или в IN[1] не блок (объект Block), или какая-то проблема с AutoCAD на твоей стороне.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Aleks_199513 от 09-07-2021, 10:35:11
Aleks_199513,
Или в IN[1] не блок (объект Block), или какая-то проблема с AutoCAD на твоей стороне.
Очень странно, но подается же объект типа Block...буду искать дальше проблему тогда, а правильный ли я выбрал метод вставки блока в таблицу(tab.SetBlockTableRecordId(1,1,1928560679024,True))? или может есть другой вариант?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 09-07-2021, 10:40:43
Aleks_199513,
Метод правильный. Если считать что переданное число - ObjectID блока.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 09-07-2021, 10:41:51
P.S.: Кстати нужно сначала задать тип ячейки.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Aleks_199513 от 09-07-2021, 10:49:43
P.S.: Кстати нужно сначала задать тип ячейки.
спасибо, сейчас буду пробовать
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Marik от 10-07-2021, 19:37:49
Подскажите, пожалуйста! Как выбрать в чертеже все примитивы начерченные определенным слоем и удалить их.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 10-07-2021, 19:43:15
Подскажите, пожалуйста! Как выбрать в чертеже все примитивы начерченные определенным слоем и удалить их.
Вы недостаточно хорошо понимаете терминологию AutoCAD. У каждого примитива есть свойство - слой (Layer). Для выбора всех примитивов на заданном слое можно воспользоваться методом SelectionSet.Select acSelectionSetAll с фильтром по слою ( группа 8 ).
Альтернативный способ - итерация по пространству модели (или пространству листа) и проверка свойства Layer для каждого из примитивов в итерации.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Алексей Кулик от 10-07-2021, 21:11:46
Я бы проходил по всей коллекции блоков и проверял объекты на слой.
Между прочим, есть команда _.-laydel, правда, она оставляет следы в ком.строке.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Marik от 10-07-2021, 22:50:13
Можно пример кода? или ссылку на пример? пожалуйста.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Алексей Кулик от 10-07-2021, 22:54:14
Если вопрос ко мне - то я лиспописатель, и не уверен, что мой вариант поможет.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 11-07-2021, 08:33:40
Наиболее простой из вариантов, проход по объектам в пространстве модели, без использования выделения:

Код - Python [Выбрать]
  1. import win32com.client
  2.  
  3. app = win32com.client.Dispatch("AutoCAD.Application")
  4. aDoc = app.ActiveDocument
  5. mSp = aDoc.ModelSpace
  6.  
  7. for obj in mSp:
  8.     if obj.Layer == "Слой_1":
  9.         obj.Delete()
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Алексей Кулик от 11-07-2021, 10:22:21
Я бы писал наподобие:
Код - Python [Выбрать]
  1. for bdef aDoc.Blocks
  2.   for ent bdef
  3.     if ent.Layer == "Layer0"
  4.       ent.Delete
Но по-хорошему тут надо добавить проверку на заблокированность / замороженность слоя - как минимум. Туда же - проход по вхождениям и определениям атрибутов, синхронизация атрибутов и т.д.
P.S. На питоне вообще не пишу.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Marik от 11-07-2021, 10:38:55
Спасибо! А нет более быстрого способа?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Алексей Кулик от 11-07-2021, 10:49:09
Только если запулить команду _.-laydel ИМХО
Но насколько это будет быстрее - вопрос.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Aleks_199513 от 15-07-2021, 14:15:11
Добрый день. Подскажите пожалуйста, как можно в автокаде найти или поставить point3d через python? Хочу применить этот метод, но не могу понять как подать туда point3d

(https://i.ibb.co/QDKMj0L/image.png) (https://ibb.co/NTyKnR5)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Алексей Кулик от 15-07-2021, 14:20:37
Point3D для Civil ИМХО немного другая история.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 15-07-2021, 20:31:46
Aleks_199513,
Point3d доступен только изнутри AutoCAD, а не через COM/ActiveX, как и вообще весь AutoCAD .NET API и Civil3D .NET API. Этот класс доступен в AcDbMgd.dll (Autodesk.AutoCAD.Geometry.Point3d)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Nutson от 29-07-2021, 06:54:16
Через COM можно добавить.


Код - Visual Basic [Выбрать]
  1. Sub testAddPointToFeatureLine()
  2.     Dim obj As AcadObject
  3.  
  4.     ThisDrawing.Utility.GetEntity obj, pp
  5.    
  6.     Dim fl As AeccLandFeatureLine
  7.     Set fl = obj
  8.     flPoints = fl.GetPoints
  9.    
  10.     i = 0
  11.     Dim util As Object
  12.     Set util = ThisDrawing.Utility
  13.     Call util.CreateTypedArray(newPoint, vbDouble, (flPoints (i) + flPoints (i + 3)) * 0.5, flPoints ((i + 1) + flPoints (i + 4)) * 0.5, 20)
  14.  
  15.     'Call fl.InsertFeaturePoint(newPoint, aeccLandFeatureLinePointPI) 'aeccLandFeatureLinePointPI = 1 отображается на плане квадратной ручкой
  16.    Call fl.InsertFeaturePoint(newPoint, aeccLandFeatureLinePointElevation) 'aeccLandFeatureLinePointElevation = 2 отображается на плане круглой ручкой
  17.  
  18. End Sub
  19.  
  20.  

Так же есть метод  InsertFeaturePoints
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Aleks_199513 от 29-07-2021, 08:02:37
Через COM можно добавить.


Код - Visual Basic [Выбрать]
  1. Sub testAddPointToFeatureLine()
  2.     Dim obj As AcadObject
  3.  
  4.     ThisDrawing.Utility.GetEntity obj, pp
  5.    
  6.     Dim fl As AeccLandFeatureLine
  7.     Set fl = obj
  8.     flPoints = fl.GetPoints
  9.    
  10.     i = 0
  11.     Dim util As Object
  12.     Set util = ThisDrawing.Utility
  13.     Call util.CreateTypedArray(newPoint, vbDouble, (flPoints (i) + flPoints (i + 3)) * 0.5, flPoints ((i + 1) + flPoints (i + 4)) * 0.5, 20)
  14.  
  15.     'Call fl.InsertFeaturePoint(newPoint, aeccLandFeatureLinePointPI) 'aeccLandFeatureLinePointPI = 1 отображается на плане квадратной ручкой
  16.    Call fl.InsertFeaturePoint(newPoint, aeccLandFeatureLinePointElevation) 'aeccLandFeatureLinePointElevation = 2 отображается на плане круглой ручкой
  17.  
  18. End Sub
  19.  
  20.  

Так же есть метод  InsertFeaturePoints
Спасибо
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Aleks_199513 от 05-08-2021, 10:48:42
Aleks_199513,  Добрый день. Подскажите пожалуйста как через Python задать номер ярлыка мультивыноски? не могу найти метод..

(https://i.ibb.co/QX2BkgG/image.jpg) (https://ibb.co/25D2S9B)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 05-08-2021, 10:59:55
Aleks_199513,
Если я правильно понял о чем, то это делается через MLeader.TextString

Название: Re: Python & ActiveX/COM Autocad
Отправлено: Aleks_199513 от 05-08-2021, 11:02:49
Если я правильно понял о чем, то это делается через MLeader.TextString
не совсем, это работает, когда стиль мультивыноски текст, а когда блок, то не работает...
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 05-08-2021, 11:03:41
Если я правильно понял о чем, то это делается через MLeader.TextString
не совсем, это работает, когда стиль мультивыноски текст, а когда блок, то не работает...
А если неправильно, то через MLeader.SetBlockAttributeValue
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Nutson от 05-08-2021, 11:04:55
На вба так, в питон наверное сами сможете переконвертировать

Код - Visual Basic [Выбрать]
  1. Sub select_obj()
  2.     Dim obj As AcadObject
  3.     ThisDrawing.Utility.GetEntity obj, pp
  4.     Dim mleader As AcadMLeader
  5.     Set mleader = obj
  6.  
  7.     Dim blc As AcadBlock
  8.     Dim blcEl As AcadEntity
  9.    
  10.    
  11.     For Each blc In ThisDrawing.Blocks
  12.         If blc.Name = mleader.ContentBlockName Then
  13.             For Each blcEl In blc
  14.                 If blcEl.ObjectName = "AcDbAttributeDefinition" Then
  15.                     Call mleader.SetBlockAttributeValue(blcEl.ObjectID, "test")
  16.                 End If
  17.             Next
  18.         End If
  19.     Next
  20. End Sub
  21.  
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Aleks_199513 от 05-08-2021, 13:46:51
А если неправильно, то через MLeader.SetBlockAttributeValue
А как сделать так, чтобы центр блока не улетал в 0,0?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Nutson от 05-08-2021, 13:48:33
А если неправильно, то через MLeader.SetBlockAttributeValue
А как сделать так, чтобы центр блока не улетал в 0,0?

Не видя Ваш код - никак :)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Aleks_199513 от 05-08-2021, 13:50:00
Не видя Ваш код - никак
Код - Python [Выбрать]
  1. import System
  2. import clr
  3. # Add Assemblies for AutoCAD and Civil3D
  4. #LinkDWG Core DYF by Koz Jono YEOH
  5. #kozmosovia@hotmail.com
  6. #Copyright(C) 1994-2020 KozMos Inc.
  7. #Copyright(C) 2011-2020 Neila Heaven Networks
  8. #Copyright(C) 2017-2020 Tachyon Intelligent Design Institute
  9. clr.AddReference('AcMgd')
  10. clr.AddReference('AcCoreMgd')
  11. clr.AddReference('AcDbMgd')
  12. clr.AddReference('AecBaseMgd')
  13. clr.AddReference('AecPropDataMgd')
  14. clr.AddReference('AeccDbMgd')
  15. clr.AddReference('ProtoGeometry')
  16.  
  17. from Autodesk.AutoCAD.Runtime import *
  18. from Autodesk.AutoCAD.ApplicationServices import *
  19. from Autodesk.AutoCAD.EditorInput import *
  20. from Autodesk.AutoCAD.DatabaseServices import *
  21. from Autodesk.AutoCAD.Geometry import *
  22.  
  23. # Import references from Civil3D
  24. from Autodesk.Civil.ApplicationServices import *
  25. from Autodesk.Civil.DatabaseServices import *
  26.  
  27. marsh = System.Runtime.InteropServices.Marshal
  28. app = marsh.GetActiveObject("Autocad.Application.24.1")
  29. aDoc = app.ActiveDocument
  30. mSp = aDoc.ModelSpace
  31. adoc = Application.DocumentManager.MdiActiveDocument
  32.  
  33. def ptA(p,x1,y1):
  34.         return System.Array[float]([p.X,p.Y,p.Z,p.X+x1,p.Y+y1,p.Z])
  35.  
  36. x1 = 5
  37. y1 = 5
  38. blockItem = None
  39. # Координаты блоков
  40. listOfPoints = IN[0]
  41. numbeTable= IN[1]
  42. Coord=[]
  43. logFile = []
  44.  
  45. import Autodesk
  46. outList = []
  47.  
  48. with adoc.LockDocument():
  49.     with adoc.Database as db:
  50.         with db.TransactionManager.StartTransaction() as t:
  51.             # Place your code below
  52.                         for i in listOfPoints:    
  53.                                 bufferOut = []
  54.                                 locOrigin = i.Origin
  55.                                 points = ptA(locOrigin,x1,y1)
  56.                                 lead = mSp.AddMLeader(points, 0)
  57.                                 bufferOut.append(lead)
  58.                                 leaderBlocks = aDoc.Blocks(lead.ContentBlockName)
  59.                                
  60.                                 if lead and hasattr(lead,"ObjectName") and lead.ObjectName=="AcDbMLeader":
  61.                                         blocks=lead.Document.Blocks.Item(lead.ContentBlockName)
  62.                                         for block in blocks:
  63.                                                 if block.ObjectName == "AcDbAttributeDefinition" and block.TagString.upper() == "НОМЕРЯРЛЫКА".upper():
  64.                                                         lead.SetBlockAttributeValue(block.ObjectId, str(numbeTable[listOfPoints.index(i)]))
  65.                                                        
  66.                                                        
  67.                                 blockItem = block
  68.             # Commit before end transaction
  69.                         t.Commit()
  70.  
  71. #lead.TextString = str(numbeTable[listOfPoints.index(i)])
  72. #ID_Name1 = (aDoc.Blocks("_TagCircle").ObjectID)
  73. #lead1= mSp.SetBlockAttributeValue(lead.ObjectID,)
  74. #lead.GetBlockAttributeValue(ID_Name1)
  75. #coord.append(points)
  76. outList = []
  77. OUT = blockItem
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Nutson от 05-08-2021, 14:08:01
Интересное поведение. Даже если при создании мульти выноски я указываю
Код - Visual Basic [Выбрать]
  1.              MleaderObj.BlockConnectionType = acConnectBase
  2.  
  3.  
Выноска создается с значением acConnectExtents.

Попробуйте после создания пошевелить это свойство выноски. Может отдельной транзакцией или регеня чертеж.
В моем случае даже так не помогло. Зато ручкой у выноски меняешь расположение блока и он сразу подтягивается к выноске
Код - Visual Basic [Выбрать]
  1.              MleaderObj.BlockConnectionType = acConnectExtents
  2.              MleaderObj.Update
  3.              MleaderObj.BlockConnectionType = acConnectBase
  4.  
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Nutson от 05-08-2021, 14:09:28
Интересное поведение. Даже если при создании мульти выноски я указываю
Код - Visual Basic [Выбрать]
  1.              MleaderObj.BlockConnectionType = acConnectBase
  2.  
  3.  
Выноска создается с значением acConnectExtents.

Попробуйте после создания пошевелить это свойство выноски. Может отдельной транзакцией или регеня чертеж.
В моем случае даже так не помогло. Зато ручкой у выноски меняешь расположение блока и он сразу подтягивается к выноске
Код - Visual Basic [Выбрать]
  1.              MleaderObj.BlockConnectionType = acConnectExtents
  2.              MleaderObj.Update
  3.              MleaderObj.BlockConnectionType = acConnectBase
  4.  

забыл , если что значения констант:
acConnectBase=1
acConnectExtents=0
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 05-08-2021, 15:04:52
Aleks_199513,
Не забывайте про правило форматирования кода на форуме (у меня в подписи)!
Код - какая-то дикая смесь AutoCAD COM/ActiveX и AutoCAD .NET API
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Aleks_199513 от 05-08-2021, 15:50:17
Aleks_199513,
Не забывайте про правило форматирования кода на форуме (у меня в подписи)!
Код - какая-то дикая смесь AutoCAD COM/ActiveX и AutoCAD .NET API
Извините.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Aleks_199513 от 05-08-2021, 15:51:14
забыл , если что значения констант:
acConnectBase=1
acConnectExtents=0
нет, к сожалению ничего не получилось. А может есть какой-то способ переместить блок?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 05-08-2021, 16:08:36
Aleks_199513,
Не увидел в коде назначения ContentBlockName и ContentBlockType
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Nutson от 05-08-2021, 16:10:39
Я сейчас перепроверил, все работает оказывается. Не заметил On error goto exit , код спотыкался об мою попытку настроить свойства текста выноски.
Так как в выноске блок вместо текста, код выходил из процедуры не доходя до настройки MleaderObj.BlockConnectionType = acConnectExtents.
Так что проверяйте код на ошибки, в цитировании помечу вероятные места

попытался выделить цветом в код блоке -не срабатывает.
строки с моими комментариям:
58, 61, 62, 63 (ошибка тут скорее всего) , 67


Не видя Ваш код - никак
Код - Python [Выбрать]
  1. import System
  2. import clr
  3. # Add Assemblies for AutoCAD and Civil3D
  4. #LinkDWG Core DYF by Koz Jono YEOH
  5. #kozmosovia@hotmail.com
  6. #Copyright(C) 1994-2020 KozMos Inc.
  7. #Copyright(C) 2011-2020 Neila Heaven Networks
  8. #Copyright(C) 2017-2020 Tachyon Intelligent Design Institute
  9. clr.AddReference('AcMgd')
  10. clr.AddReference('AcCoreMgd')
  11. clr.AddReference('AcDbMgd')
  12. clr.AddReference('AecBaseMgd')
  13. clr.AddReference('AecPropDataMgd')
  14. clr.AddReference('AeccDbMgd')
  15. clr.AddReference('ProtoGeometry')
  16.  
  17. from Autodesk.AutoCAD.Runtime import *
  18. from Autodesk.AutoCAD.ApplicationServices import *
  19. from Autodesk.AutoCAD.EditorInput import *
  20. from Autodesk.AutoCAD.DatabaseServices import *
  21. from Autodesk.AutoCAD.Geometry import *
  22.  
  23. # Import references from Civil3D
  24. from Autodesk.Civil.ApplicationServices import *
  25. from Autodesk.Civil.DatabaseServices import *
  26.  
  27. marsh = System.Runtime.InteropServices.Marshal
  28. app = marsh.GetActiveObject("Autocad.Application.24.1")
  29. aDoc = app.ActiveDocument
  30. mSp = aDoc.ModelSpace
  31. adoc = Application.DocumentManager.MdiActiveDocument
  32.  
  33. def ptA(p,x1,y1):
  34.         return System.Array[float]([p.X,p.Y,p.Z,p.X+x1,p.Y+y1,p.Z])
  35.  
  36. x1 = 5
  37. y1 = 5
  38. blockItem = None
  39. # Координаты блоков
  40. listOfPoints = IN[0]
  41. numbeTable= IN[1]
  42. Coord=[]
  43. logFile = []
  44.  
  45. import Autodesk
  46. outList = []
  47.  
  48. with adoc.LockDocument():
  49.     with adoc.Database as db:
  50.         with db.TransactionManager.StartTransaction() as t:
  51.             # Place your code below
  52.                         for i in listOfPoints:    
  53.                                 bufferOut = []
  54.                                 locOrigin = i.Origin
  55.                                 points = ptA(locOrigin,x1,y1)
  56.                                 lead = mSp.AddMLeader(points, 0)
  57.                                 bufferOut.append(lead)
  58.                                 leaderBlocks = aDoc.Blocks(lead.ContentBlockName)  [color=red] [u]Вот эта строка повторяется тремя строками ниже[/u][/color]
  59.                                
  60.                                 if lead and hasattr(lead,"ObjectName") and lead.ObjectName=="AcDbMLeader":
  61.                                         blocks=lead.Document.Blocks.Item(lead.ContentBlockName)  [color=red] здесь[/color]
  62.                                         for block in blocks:  // здесь block по факту это acadEntity, то есть элементы из которых состоит определение блока
  63.                                                 if block.ObjectName == "AcDbAttributeDefinition" and block.TagString.upper() == "НОМЕРЯРЛЫКА".upper():  [color=red]   block.TagString.upper() == "НОМЕРЯРЛЫКА".upper()  - вот тут скорее всего спотыкается код. Так как ентити может быть линией и у нее нет такого свойства[/color]
  64.                                                         lead.SetBlockAttributeValue(block.ObjectId, str(numbeTable[listOfPoints.index(i)]))
  65.                                                        
  66.                                                        
  67.                                 blockItem = block[color=red]  ну это тоже не то пальто[/color]
  68.             # Commit before end transaction
  69.                         t.Commit()
  70.  
  71. #lead.TextString = str(numbeTable[listOfPoints.index(i)])
  72. #ID_Name1 = (aDoc.Blocks("_TagCircle").ObjectID)
  73. #lead1= mSp.SetBlockAttributeValue(lead.ObjectID,)
  74. #lead.GetBlockAttributeValue(ID_Name1)
  75. #coord.append(points)
  76. outList = []
  77. OUT = blockItem
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Aleks_199513 от 05-08-2021, 16:21:55
Я сейчас перепроверил, все работает оказывается. Не заметил On error goto exit , код спотыкался об мою попытку настроить свойства текста выноски.
Так как в выноске блок вместо текста, код выходил из процедуры не доходя до настройки MleaderObj.BlockConnectionType = acConnectExtents.
Так что проверяйте код на ошибки, в цитировании помечу вероятные места

попытался выделить цветом в код блоке -не срабатывает.
строки с моими комментариям:
58, 61, 62, 63 (ошибка тут скорее всего) , 67



Не видя Ваш код - никак
Код - Python [Выбрать]
  1. import System
  2. import clr
  3. # Add Assemblies for AutoCAD and Civil3D
  4. #LinkDWG Core DYF by Koz Jono YEOH
  5. #kozmosovia@hotmail.com
  6. #Copyright(C) 1994-2020 KozMos Inc.
  7. #Copyright(C) 2011-2020 Neila Heaven Networks
  8. #Copyright(C) 2017-2020 Tachyon Intelligent Design Institute
  9. clr.AddReference('AcMgd')
  10. clr.AddReference('AcCoreMgd')
  11. clr.AddReference('AcDbMgd')
  12. clr.AddReference('AecBaseMgd')
  13. clr.AddReference('AecPropDataMgd')
  14. clr.AddReference('AeccDbMgd')
  15. clr.AddReference('ProtoGeometry')
  16.  
  17. from Autodesk.AutoCAD.Runtime import *
  18. from Autodesk.AutoCAD.ApplicationServices import *
  19. from Autodesk.AutoCAD.EditorInput import *
  20. from Autodesk.AutoCAD.DatabaseServices import *
  21. from Autodesk.AutoCAD.Geometry import *
  22.  
  23. # Import references from Civil3D
  24. from Autodesk.Civil.ApplicationServices import *
  25. from Autodesk.Civil.DatabaseServices import *
  26.  
  27. marsh = System.Runtime.InteropServices.Marshal
  28. app = marsh.GetActiveObject("Autocad.Application.24.1")
  29. aDoc = app.ActiveDocument
  30. mSp = aDoc.ModelSpace
  31. adoc = Application.DocumentManager.MdiActiveDocument
  32.  
  33. def ptA(p,x1,y1):
  34.         return System.Array[float]([p.X,p.Y,p.Z,p.X+x1,p.Y+y1,p.Z])
  35.  
  36. x1 = 5
  37. y1 = 5
  38. blockItem = None
  39. # Координаты блоков
  40. listOfPoints = IN[0]
  41. numbeTable= IN[1]
  42. Coord=[]
  43. logFile = []
  44.  
  45. import Autodesk
  46. outList = []
  47.  
  48. with adoc.LockDocument():
  49.     with adoc.Database as db:
  50.         with db.TransactionManager.StartTransaction() as t:
  51.             # Place your code below
  52.                         for i in listOfPoints:    
  53.                                 bufferOut = []
  54.                                 locOrigin = i.Origin
  55.                                 points = ptA(locOrigin,x1,y1)
  56.                                 lead = mSp.AddMLeader(points, 0)
  57.                                 bufferOut.append(lead)
  58.                                 leaderBlocks = aDoc.Blocks(lead.ContentBlockName)  [color=red] [u]Вот эта строка повторяется тремя строками ниже[/u][/color]
  59.                                
  60.                                 if lead and hasattr(lead,"ObjectName") and lead.ObjectName=="AcDbMLeader":
  61.                                         blocks=lead.Document.Blocks.Item(lead.ContentBlockName)  [color=red] здесь[/color]
  62.                                         for block in blocks:  // здесь block по факту это acadEntity, то есть элементы из которых состоит определение блока
  63.                                                 if block.ObjectName == "AcDbAttributeDefinition" and block.TagString.upper() == "НОМЕРЯРЛЫКА".upper():  [color=red]   block.TagString.upper() == "НОМЕРЯРЛЫКА".upper()  - вот тут скорее всего спотыкается код. Так как ентити может быть линией и у нее нет такого свойства[/color]
  64.                                                         lead.SetBlockAttributeValue(block.ObjectId, str(numbeTable[listOfPoints.index(i)]))
  65.                                                        
  66.                                                        
  67.                                 blockItem = block[color=red]  ну это тоже не то пальто[/color]
  68.             # Commit before end transaction
  69.                         t.Commit()
  70.  
  71. #lead.TextString = str(numbeTable[listOfPoints.index(i)])
  72. #ID_Name1 = (aDoc.Blocks("_TagCircle").ObjectID)
  73. #lead1= mSp.SetBlockAttributeValue(lead.ObjectID,)
  74. #lead.GetBlockAttributeValue(ID_Name1)
  75. #coord.append(points)
  76. outList = []
  77. OUT = blockItem
  а вы проверяли работу на VBA?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Nutson от 05-08-2021, 16:42:07
Ваш код полностью моделить не буду, но вот вам наглядно что когда вы пишите For each по block, происходит перебор составляющих определения блока. Среди них не только атрибуты поэтому обращать к свойству которое есть только у атрибута это ошибка.  Я ведь уже написал.
Вообще советую тестироваться самому на ВБА так как в питоне(в данном случае из под динамо) просто нет функций по дебагу кода, отсюда такие ошибки
(https://i.postimg.cc/c6D2HgRS/2021-08-05-20-37-46.png) (https://postimg.cc/c6D2HgRS)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Aleks_199513 от 05-08-2021, 17:10:21
Ваш код полностью моделить не буду, но вот вам наглядно что когда вы пишите For each по block, происходит перебор составляющих определения блока. Среди них не только атрибуты поэтому обращать к свойству которое есть только у атрибута это ошибка.  Я ведь уже написал.
Вообще советую тестироваться самому на ВБА так как в питоне(в данном случае из под динамо) просто нет функций по дебагу кода, отсюда такие ошибки
Спасибо. Решил проблему просто изменением стиля выноски.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Nutson от 05-08-2021, 17:12:16
Не сказать что решили, отсрочили)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Шашлык от 01-09-2021, 01:43:14
Подскажите, пожалуйста, что-то я уже изломал голову или просто не внимательно смотрю инфу
Я хочу создать видовой лист, например А3
Как мне указать для видового экрана границу именно для данного формата + вписать туда чертёж ?
Я могу создать лист с параметрами, но не понимаю какими методами сделать границу (как понимаю масштаб)
Руками я это делаю как: подгоняю границу под формат листа и через ПОКАЗАТЬ зумирую необходимую область модели
Хотелось бы это делать на автомате
Искать блоки рамок я могу

(https://i.ibb.co/jyFqWLf/Sx-G3-T894r-o.jpg) (https://ibb.co/2vBRsjh)
найти и скачать картинки (https://ru.imgbb.com/)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Nutson от 02-09-2021, 06:46:14
Посмотрите здесь
http://www.alex160570.narod.ru/AcadVBA/vba10.htm
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Aleks_199513 от 08-10-2021, 17:06:57
Добрый день. Подскажите пожалуйста, как можно получить координаты вершин полилинии в Python?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 08-10-2021, 18:07:07
Добрый день. Подскажите пожалуйста, как можно получить координаты вершин полилинии в Python?
Свойство Coordinates.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: vxv от 16-10-2021, 17:49:56
Доброго времени суток.
Чтобы переопределить текст в линейном размере используется метод:
Код - Python [Выбрать]
  1. object.TextOverride = 'Новый текст'
Запись типа:
Код - Python [Выбрать]
  1. Text = object.TextOverride
  2. print('Text = ', Text)
не выдает ошибку, но ни чего и не выводит в консоль.
Подскажите пожалуйста, как прочитать текст из линейного размера?
Спасибо
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 16-10-2021, 17:54:05
не выдает ошибку, но ни чего и не выводит в консоль.
Ничего не выводит или выводит
Text =как будто текст пустой?
Если да, то это нормально. Значит текст не переопределён.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: vxv от 16-10-2021, 18:07:15
не выдает ошибку, но ни чего и не выводит в консоль.
Ничего не выводит или выводит
Text =как будто текст пустой?
Если да, то это нормально. Значит текст не переопределён.
Выводит:
Text =
А как в таком случае прочитать текст из размера? Все методы уже перепробовал с официального сайта Автокада
Название: Re: Python & ActiveX/COM Autocad
Отправлено: vxv от 16-10-2021, 18:10:15
И кстате я ищу не эту строчку
Код - Python [Выбрать]
  1. print('Величина размера = ', object.Measurement)
Она как раз находит величину размера.
А мне нужны данные из "Текстовая строка" в свойстве размера
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 16-10-2021, 18:11:33
А как в таком случае прочитать текст из размера?
Похоже, что средствами COM/ActiveX это сделать не просто. Можно расчленить размер, вытащить текст, отменить изменения.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: vxv от 16-10-2021, 18:15:04
А как в таком случае прочитать текст из размера?
Похоже, что средствами COM/ActiveX это сделать не просто. Можно расчленить размер, вытащить текст, отменить изменения.
Я тоже об этом думал, но это не то чего бы хотелось
Средствами .Net подходит вроде метод DimensionText, но я понятия не имею как с этим работать
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 16-10-2021, 18:44:51
Средствами .Net подходит вроде метод DimensionText, но я понятия не имею как с этим работать
Из Python? Если он не запускается изнутри AutoCAD - то никак. Ибо AutoCAD .NET API можно использовать только изнутри AutoCAD.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 16-10-2021, 18:48:17
И кстате я ищу не эту строчку
Код - Python [Выбрать]
  1. print('Величина размера = ', object.Measurement)
Она как раз находит величину размера.
А мне нужны данные из "Текстовая строка" в свойстве размера
А в чем у тебя разница между этими значениями? Посмотри еще свойства TextPrefix и TextSuffix
Название: Re: Python & ActiveX/COM Autocad
Отправлено: vxv от 16-10-2021, 20:44:51
Александр Ривилис, большое спасибо за помощь, разобрался, моя вина не доглядел, слишком много было данных для выбора, проглядел. Ответ таков: object.TextOverride собирает данные))))))
Прошу прощения
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 16-10-2021, 20:55:04
Я просто не пойму раз есть метод ввода данных в Текстовую строку, почему нельзя их от туда прочитать
С размером связан блок, внутри которого МТекст, отрезки и т.д. Эту связь можно отследить (и соответственно получить содержимое МТекст) в Lisp/.NET/ObjectARX, но не в COM/ActiveX
Название: Re: Python & ActiveX/COM Autocad
Отправлено: vxv от 22-10-2021, 11:28:53
Подскажите пожалуйста, как получить количество линий выноски у «Позиционной выноски» элемента Autodesk SPDS Extension? Или где про это можно найти документацию? Методы от стандартной мультивыноски работают не асе.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 22-10-2021, 15:23:33
Или где про это можно найти документацию?
Это не документировано. Все доступные из COM/ActiveX свойства можно получить при помощи метода VisualLisp https://help.autodesk.com/view/OARX/2019/RUS/?guid=GUID-BCE56B30-54A6-42F9-8910-81AF2B7B9AA8
В командной строке AutoCAD набираешь и выбираешь "Позиционную выноску":

Код - Auto/Visual Lisp [Выбрать]
  1. (vlax-dump-object (vlax-ename->vla-object (car (entsel))) t)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: vxv от 25-10-2021, 16:44:59
Подскажите пожалуйста, как узнать есть у меня уже блок или нет в базе данных, с определенным именем . А то постоянно дорисовываю одно и тоже в блоке. Спасибо
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 25-10-2021, 20:52:07
vxv,
ThisDrawing.Blocks.Item("Имя Блока")
Название: Re: Python & ActiveX/COM Autocad
Отправлено: vxv от 25-10-2021, 23:57:36
Спасибо, большое. Заработало, стоило было чуть подправить под себя, а именно, вдруг кто не знает:

Код - Python [Выбрать]
  1. import win32com.client
  2. from pythoncom import VT_ARRAY, VT_R8, VT_DISPATCH
  3. acad = win32com.client.Dispatch("AutoCAD.Application")
  4. doc = acad.ActiveDocument
  5.  
  6. try:
  7.     doc.Blocks.Item("Blo_STSM")
  8. except:
  9.     creatBlock_STSM() #функция создания блока
Название: Re: Python & ActiveX/COM Autocad
Отправлено: vxv от 26-10-2021, 23:47:35
Доброго времени суток, не пойму почему не загружается тип линии по следующему коду:
Код - Python [Выбрать]
  1. import win32com.client
  2. acad = win32com.client.Dispatch("AutoCAD.Application")
  3. doc = acad.ActiveDocument
  4. acCurDb = doc.Database
  5. acCurDb.LoadLineTypeFile('ограждение1', 'acadiso.lin')
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 26-10-2021, 23:52:07
vxv,
Наверное потому, что метода LoadLineTypeFile нет у Database.
Зато есть метод Load (пример из документации):
Код - Visual Basic [Выбрать]
  1. Sub Example_Load()
  2.     ' This example attempts to load the linetype "CENTER" from
  3.    ' the acad.lin file. If the linetype already exists, then
  4.    ' a message is displayed.
  5.    
  6.     Dim linetypeName As String
  7.     linetypeName = "CENTER"
  8.    
  9.     ' Load "CENTER" line type from acad.lin file
  10.    On Error Resume Next    ' trap any load errors
  11.    ThisDrawing.Linetypes.Load linetypeName, "acad.lin"
  12.    
  13.     ' If the name already exists, then notify user
  14.    If Err.Description = "Duplicate record name" Then
  15.         MsgBox "A line type named '" & linetypeName & "' already exists.", , "Load Example"
  16.     End If
  17.    
  18. End Sub
Название: Re: Python & ActiveX/COM Autocad
Отправлено: vxv от 27-10-2021, 06:22:32
Спасибо за наводку. Заработало. Вот что получилось:
Код - Python [Выбрать]
  1. import win32com.client
  2. acad = win32com.client.Dispatch("AutoCAD.Application")
  3. doc = acad.ActiveDocument
  4. try:
  5.     doc.Linetypes.Load('ограждение1', 'acadiso.lin')
  6. except:
  7.     pass
Название: Re: Python & ActiveX/COM Autocad
Отправлено: vxv от 28-10-2021, 16:23:17
Доброго времени суток, подскажите пожалуйста, почему не получается создать символ стрелки стиля выноски методом object.ArrowSymbol

Код - Python [Выбрать]
  1. acad = win32com.client.Dispatch("AutoCAD.Application")
  2. doc = acad.ActiveDocument
  3. Dictionary = doc.Dictionaries.Item("ACAD_MLEADERSTYLE")
  4. NewStyle = Dictionary.AddObject("NewStyle", "AcDbMLeaderStyle")
  5. NewStyle.ArrowSymbol =  "_Dot"

А выдает следующую ошибку:
 self._oleobj_.Invoke(entry.dispid, 0, invoke_type, 0, value)pywintypes.com_error: (-2147352567, 'Ошибка.', (0, 'AutoCAD.Application', 'Ключ не найден', 'C:\\Program Files\\Autodesk\\AutoCAD 2017\\HELP\\OLE_ERR.CHM', -2145386476, -2145386476), None)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Алексей Кулик от 28-10-2021, 16:26:05
Сначала надо установить системную переменную DIMBLK, а потом уже назначать ArrowSymbol. Естественно, не забыв вернуть DIMBLK обратно.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: vxv от 28-10-2021, 16:27:48
Сначала надо установить системную переменную DIMBLK, а потом уже назначать ArrowSymbol. Естественно, не забыв вернуть DIMBLK обратно.
Разобрался, спасибо большое. Вот так будет выглядеть код:

Код - Python [Выбрать]
  1. acad = win32com.client.Dispatch("AutoCAD.Application")
  2. doc = acad.ActiveDocument
  3. Dictionary = doc.Dictionaries.Item("ACAD_MLEADERSTYLE")
  4. NewStyle = Dictionary.AddObject("NewStyle", "AcDbMLeaderStyle")
  5. doc.SetVariable('DIMBLK', "_Dot")
  6. NewStyle.ArrowSymbol =  "_Dot"
  7. doc.SetVariable('DIMBLK', ".")
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 28-10-2021, 18:22:32
vxv,
Очень желательно эту системную переменную вернуть в исходное состояние (как и практически любую другую системную переменную).
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Aleks_199513 от 29-10-2021, 09:30:11
Доброго времени суток, Может кто-нибудь знает как получить доступ к именам блоков которые входят в состав многовидового блока?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Алексей Кулик от 29-10-2021, 09:40:57
Многовидовой блок - это же вроде что-то из вертикалок типа AA / MEP ?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 29-10-2021, 14:27:28
Доброго времени суток, Может кто-нибудь знает как получить доступ к именам блоков которые входят в состав многовидового блока?
Нашел такое в документации. Попробуй адаптировать:

Код - Visual Basic [Выбрать]
  1. Sub Example_Name_AecViewBlocks()
  2.  
  3. 'This example shows the number of colors of the owner of the Viewblock collection
  4.  
  5.     Dim obj As Object
  6.     Dim pt As Variant
  7.     Dim blockRef As AecMVBlockRef
  8.     Dim viewBlocks As AecViewBlocks
  9.    
  10.     ThisDrawing.Utility.GetEntity obj, pt, "Select a Multiview Block"
  11.     If TypeOf obj Is AecMVBlockRef Then
  12.         Set blockRef = obj
  13.         Set viewBlocks = blockRef.viewBlocks
  14.         MsgBox "Colors of MVBlockRef Owner: " & viewBlocks.MVBlockRef.Color, vbInformation, "MVBlockRef Example"
  15.     Else
  16.         MsgBox "Not a Multiview Block", vbInformation, "MVBlockRef Example"
  17.     End If
  18.  
  19. End Sub
Название: Re: Python & ActiveX/COM Autocad
Отправлено: vxv от 11-11-2021, 21:24:56
Здравствуйте, кто-нибудь работал с СПДС GraphiCS от Csoft? В нем присутствует такой элемент как "Формат". Нужно как то добраться до значения всех атрибутов основной надписи или штампа по простому и прочитать значения всех ячеек из него.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 11-11-2021, 21:48:27
Здравствуйте, кто-нибудь работал с СПДС GraphiCS от Csoft? В нем присутствует такой элемент как "Формат". Нужно как то добраться до значения всех атрибутов основной надписи или штампа по простому и прочитать значения всех ячеек из него.
Код - Auto/Visual Lisp [Выбрать]
  1. (progn
  2.  (vl-load-com)
  3.  (vlax-dump-object (vlax-ename->vla-object (car (entsel))))
  4. )
Если это что-то полезное даст в командной строке AutoCAD, то это полезное ты сможешь получить и в Python.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Marik от 14-01-2022, 22:13:40
Подскажите, пожалуйста. Пытаюсь загрузить внешнюю ссылку в открытый файл dwg. Программа выдает такую ошибку:
"File "<COMObject <unknown>>", line 5, in AttachExternalReference
pywintypes.com_error: (-2147352567, 'Ошибка.', (0, 'AutoCAD.Application', 'Ошибка при доступе к файлу', 'C:\\Program Files\\Autodesk\\AutoCAD 2016\\HELP\\OLE_ERR.CHM', -2145386426, -2145386426), None)".
Что делаю не так? Вот код:

Код - Python [Выбрать]
  1. import win32com.client
  2. from pythoncom import VT_R8, VT_ARRAY, VT_DISPATCH, VT_VARIANT
  3.  
  4. appAutocad = win32com.client.GetActiveObject("AutoCAD.Application")
  5. aDoc = appAutocad.ActiveDocument
  6. mSp = aDoc.ModelSpace
  7.  
  8. def acadcoord(*args):
  9.     if isinstance(args[0], (list, tuple)):
  10.         coords = [item for item in args[0]]
  11.     else:
  12.         coords = args
  13.     return win32com.client.VARIANT(VT_ARRAY | VT_R8, coords)
  14.  
  15. mSp.AttachExternalReference("G:\Python\d1020ntr.dwg","Xref01",acadcoord(0, 0, 0),1,1,1,0,False)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 14-01-2022, 22:40:48
Marik,
А разве не так должно быть:
Код - Python [Выбрать]
  1. mSp.AttachExternalReference("G:\\Python\\d1020ntr.dwg","Xref01",acadcoord(0, 0, 0),1,1,1,0,False)
?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Marik от 15-01-2022, 14:12:44
Может и с "\\", только все равно ошибка. Пробовал и с "/" - тоже ошибка.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 15-01-2022, 16:47:08
Marik,
1. К этому каталогу есть доступ по записи?
2. Этот dwg-файл открывается нормально в этой же версии AutoCAD?
3. Нет ли ошибки в пути доступа к файлу?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Electric от 15-01-2022, 18:02:02
Может и с "\\", только все равно ошибка. Пробовал и с "/" - тоже ошибка.

Я на диске "G:\" создал папку "Python", в ней файл "d1020ntr.dwg".
Твой код с предложенными изменениями от Александра работает, геометрия из "d1020ntr.dwg" вставляется внешней ссылкой.

Попробуй как вариант с добавлением "r" перед строкой:

Код - Python [Выбрать]
  1. mSp.AttachExternalReference(r"G:\Python\d1020ntr.dwg", "Xref01", acadcoord(0, 0, 0), 1, 1, 1, 0, False)

если не хочешь дублировать слэш каждый раз.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Marik от 16-01-2022, 00:26:53
Спасибо за помощь! Работает без "r" и с "\". Файл - ссылка был поврежден почему-то.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: qwertyqwertevich от 25-03-2022, 15:40:51
Добрый день. Подскажите, пожалуйста, как получить цвет объекта в чём-то помимо ACI? Искал по этой теме, видел только применение RGB, но получить TrueColor объекта у меня не получилось. В общем надо чтобы программа понимала в какой RAL выкрашен объект
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 25-03-2022, 16:02:31
Добрый день. Подскажите, пожалуйста, как получить цвет объекта в чём-то помимо ACI? Искал по этой теме, видел только применение RGB, но получить TrueColor объекта у меня не получилось. В общем надо чтобы программа понимала в какой RAL выкрашен объект
В COM/ActiveX API, которое использует Python, таких средств нет. Тут необходимо создать массив, в котором будет соответствие ACI номера и цвета RGB. Например, как сделано здесь: https://forums.autodesk.com/t5/vba/converting-colors-to-rgb/td-p/350909
Но вообще-то соответствия ACI-номеров и RGB разные в разных версиях AutoCAD и еще зависят от цветовой схемы AutoCAD.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: qwertyqwertevich от 25-03-2022, 16:58:22
Добрый день. Подскажите, пожалуйста, как получить цвет объекта в чём-то помимо ACI? Искал по этой теме, видел только применение RGB, но получить TrueColor объекта у меня не получилось. В общем надо чтобы программа понимала в какой RAL выкрашен объект
В COM/ActiveX API, которое использует Python, таких средств нет. Тут необходимо создать массив, в котором будет соответствие ACI номера и цвета RGB. Например, как сделано здесь: https://forums.autodesk.com/t5/vba/converting-colors-to-rgb/td-p/350909
Но вообще-то соответствия ACI-номеров и RGB разные в разных версиях AutoCAD и еще зависят от цветовой схемы AutoCAD.
Спасибо. К сожалению через соответствие ACI не получится определять RAL, ибо первые же RAL'ы в RGB эквиваленте определяются одним и тем же ACI (близкие оттенки). Что ж, еще один "за" в сторону С#, в котором такие мелочи реализуемы?
Хотя в данном случае обойдусь называнием слоя нужным RAL'ом
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 25-03-2022, 20:18:30
Что ж, еще один "за" в сторону С#, в котором такие мелочи реализуемы?
Средствами ObjectARX или AutoCAD .NET API для каждого ACI можно получить RGB.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Derie1 от 07-04-2022, 18:07:41
Добрый день.
Хотел бы вернуться к вопросу выбора и удаления определенных блоков в чертеже. Вроде бы тщательно изучил в этой ветке комментарии по этой теме, написал скрипт согласно этому и столкнулся с проблемой. Иногда скрипт отрабатывает и удаляет все нужные (ненужные) блоки, а иногда застревает на каком то шаге и вылетает с ошибкой. В чем может быть проблема?
Пробовал перебирать блоки двумя способами, в обоих одинаковая проблема возникает. Второй способ закомментирован.


Код - Python [Выбрать]
  1. import win32com.client
  2. import pythoncom
  3. from PyQt5 import QtWidgets
  4.  
  5.  
  6. app = QtWidgets.QApplication([])
  7. acad = win32com.client.Dispatch("AutoCAD.Application")
  8. dwg_file = QtWidgets.QFileDialog.getOpenFileName(caption="Выберите файл шаблона или схемы в AutoCAD... ", filter="DWG (*.dwg)")[0]  # выбираем исхоный файл
  9. doc = acad.Documents.Open(dwg_file)
  10.  
  11. try:
  12.     for i in doc.SelectionSets:
  13.         i.Delete()
  14. except:
  15.     pass
  16.  
  17. objSS = doc.SelectionSets.Add("toErase")
  18.  
  19. FilterType = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_I2, [0])
  20. FilterData = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_VARIANT, ['INSERT'])
  21. SELECT_ALL = 5
  22.  
  23. objSS.Select(SELECT_ALL, pythoncom.Empty, pythoncom.Empty, FilterType, FilterData)
  24.  
  25. i = 0
  26. while i < objSS.Count:
  27.     if objSS[i].EffectiveName == "TOTAL" or objSS[i].EffectiveName == "KNF" or objSS[i].EffectiveName == "INCOMER" or objSS[i].EffectiveName == "AUTOMAT" or objSS[i].EffectiveName == "LINE":
  28.         objSS[i].Delete()
  29.     i += 1
  30.  
  31. # for obj in objSS:
  32. #     if obj.EffectiveName == "TOTAL" or obj.EffectiveName == "KNF" or obj.EffectiveName == "INCOMER" or obj.EffectiveName == "AUTOMAT" or obj.EffectiveName == "LINE":
  33. #         obj.Delete()
  34.  
  35. objSS.Delete()

Вот текст ошибки:
Цитировать
Traceback (most recent call last):
  File "c:\Users\m.davydov\Dropbox\MyProg\SLD_Builder\deleting_selected_blocks.py", line 35, in <module>
    if objSS.EffectiveName == "TOTAL" or objSS.EffectiveName == "KNF" or objSS.EffectiveName == "INCOMER" or objSS.EffectiveName == "AUTOMAT" or objSS.EffectiveName == "LINE":
  File "C:\Users\m.davydov\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\win32com\client\dynamic.py", line 324, in __getitem__
    return self._get_good_object_(self._enum_.__getitem__(index))
  File "C:\Users\m.davydov\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\win32com\client\util.py", line 41, in __getitem__
    return self.__GetIndex(index)
  File "C:\Users\m.davydov\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\win32com\client\util.py", line 62, in __GetIndex
    result = self._oleobj_.Next(1)
pywintypes.com_error: (-2147418111, 'Вызов был отклонен.', None, None)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 07-04-2022, 18:11:02
Derie1,
Приветствую на форуме! Обрати внимание на правило форматирования кода, ссылка на которое у меня в подписи.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Derie1 от 07-04-2022, 18:13:49
Derie1,
Приветствую на форуме! Обрати внимание на правило форматирования кода, ссылка на которое у меня в подписи.

Да, спасибо. Не понял сразу как сделать. Теперь разобрался.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 07-04-2022, 18:14:10
а иногда застревает на каком то шаге и вылетает с ошибкой.
С какой ошибкой?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Derie1 от 07-04-2022, 18:16:28
С какой ошибкой?
Добавил текст ошибки в своё сообщение.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 07-04-2022, 18:19:16
С какой ошибкой?
Добавил текст ошибки в своё сообщение.
При этой ошибке можешь попробовать сделать небольшую задержку и повторить вызов.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 07-04-2022, 18:21:04
Кроме того могу посоветовать сделать цикл не от 0 до objSS.Count, а от objSS.Count до 0 с уменьшением i
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Derie1 от 07-04-2022, 22:10:21
Странно, тестирую этот код на домашнем компьютере, работает без сбоев. Причем все операции делаются заметно быстрее. Уже раз 50 запускал, ни одного сбоя нет.
На работе 2021 AutoCAD, дома 2015.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 07-04-2022, 22:19:49
Derie1,
Оба AutoCAD x64? Вообще очень много зависит от версии Windows, версии AutoCAD, дополнительно установленных программ и обновлений Windows/AutoCAD, права (администратор/пользователь) в Windows.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Derie1 от 07-04-2022, 22:43:11
Александр Ривилис,
да, обе версии x64. Ну да, дома права администратора, да и процессор в домашнем компе побыстрее, если это влияет, конечно. Но отрабатывает скрипт значительно быстрее на домашнем. Видно на глаз даже. Ладно, завтра буду пробовать задержку ставить при ошибке.
Я так понимаю, цикл надо примерно так переписать?
Код - Python [Выбрать]
  1. for obj in objSS:
  2.     try:
  3.         if obj.EffectiveName == "TOTAL" or obj.EffectiveName == "KNF" or obj.EffectiveName == "INCOMER" or obj.EffectiveName == "AUTOMAT" or obj.EffectiveName == "LINE":
  4.             obj.Delete()
  5.     except:
  6.         time.sleep(0.1)
  7.         if obj.EffectiveName == "TOTAL" or obj.EffectiveName == "KNF" or obj.EffectiveName == "INCOMER" or obj.EffectiveName == "AUTOMAT" or obj.EffectiveName == "LINE":
  8.             obj.Delete()
  9.  
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 07-04-2022, 23:25:08
Я так понимаю, цикл надо примерно так переписать?
Нет. Во-первых, выше я написал как нужно организовать цикл (от последнего элемента к первому). Во-вторых, нужен какой-то счетчик количества повторений при ошибке (например, не больше 100). Иначе возможно зацикливание.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Derie1 от 08-04-2022, 17:05:48
В итоге поставил задержку 2 секунды перед строчкой:

Код - Python [Выбрать]
  1. time.sleep(2)
  2. objSS = doc.SelectionSets.Add("toErase")
  3.  

Полностью это проблему не решило, но ошибок стало значительно меньше.
Кстати, ни разу не видел, а возможно ли сделать дополнительный SelectionSet, отобрать в него только те элементы, которые надо удалить, и потом разом их все удалить, не перебирая циклом каждый?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 08-04-2022, 17:15:43
Кстати, ни разу не видел, а возможно ли сделать дополнительный SelectionSet, отобрать в него только те элементы, которые надо удалить, и потом разом их все удалить, не перебирая циклом каждый?
Если мне не изменяет память, то objSS.Erase() должно удалить все примитивы из набора.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: dlobyntsev от 11-04-2022, 18:12:20
pywintypes.com_error: (-2147418111, 'Вызов был отклонен.', None, None)
Это ошибка COM в Windows, характерна не только для AutoCAD, но и для других приложений, например, Excel. Зависит от кучи разных вещей, начиная от версии Windows и её обновлений, версии AutoCAD и заканчивая быстродействием компьютера, не нашёл какой-то стабильной закономерности. Причина, насколько я понимаю в том, что COM не поддерживает очередь обработки, и, похоже, если AutoCAD занят в то время, кода ему выдается новая команда, то запрос отклоняется. Естественно, что добавление задержек в позволяет уменьшить проблему, но это лишь лечение симптомов.
Более-менее работающий вариант на базе кода со Stack Overflow за авторством Erik Sällström, который, однако, не даёт 100% результата:

Код - Python [Выбрать]
  1. import win32com.client
  2. from pywintypes import com_error
  3. from time import sleep
  4.  
  5. #Настройки задержек
  6. _DELAY = 0.1  # секунд
  7. _TIMEOUT = 20.0  # секунд
  8.  
  9. #Создаем служебную функцию
  10. def _com_call_wrapper(f, *args, **kwargs):
  11.     """
  12.    Повторяет вызов при получении ошибки 'Call was rejected by callee/Вызов был отклонён.'
  13.    Повторение выполняется с задержкой n*_DELAY секунд где n - количество ошибок при обращении к COM. Повторение до тех пор, пока задержка не станет равной _TIMEOUT
  14.    """
  15.     # Обрабатываем аргументы
  16.     args = [arg._wrapped_object if isinstance(arg, ComWrapper) else arg for arg in args]
  17.     kwargs = dict([(key, value._wrapped_object)
  18.                    if isinstance(value, ComWrapper)
  19.                    else (key, value)
  20.                    for key, value in dict(kwargs).items()])
  21.  
  22.     start_time = None
  23.     n = 1
  24.     while True:
  25.         try:
  26.             result = f(*args, **kwargs)
  27.         except com_error as e:
  28.             if e.hresult == -2147418111:
  29.                 if start_time is None:
  30.                     start_time = time.time()
  31.                 elif time.time() - start_time >= _TIMEOUT:
  32.                     raise
  33.                 time.sleep(_DELAY*n)
  34.                 n += 1
  35.                 continue
  36.             raise
  37.         break
  38.  
  39.     if isinstance(result, win32com.client.CDispatch) or callable(result):
  40.         return ComWrapper(result)
  41.     return result
  42.  
  43. class ComWrapper(object):
  44.     """
  45.    Объект-обёртка, который позволяет перехватывать вызовы к исходному объекту и оборачивать их в служебную функцию _com_call_wrapper
  46.    """
  47.  
  48.     def __init__(self, wrapped_object):
  49.         assert isinstance(wrapped_object, win32com.client.CDispatch) or callable(wrapped_object)
  50.         self.__dict__['_wrapped_object'] = wrapped_object
  51.  
  52.     def __getattr__(self, item):
  53.         return _com_call_wrapper(self._wrapped_object.__getattr__, item)
  54.  
  55.     def __getitem__(self, item):
  56.         return _com_call_wrapper(self._wrapped_object.__getitem__, item)
  57.  
  58.     def __setattr__(self, key, value):
  59.         _com_call_wrapper(self._wrapped_object.__setattr__, key, value)
  60.  
  61.     def __setitem__(self, key, value):
  62.         _com_call_wrapper(self._wrapped_object.__setitem__, key, value)
  63.  
  64.     def __call__(self, *args, **kwargs):
  65.         return _com_call_wrapper(self._wrapped_object.__call__, *args, **kwargs)
  66.  
  67.     def __repr__(self):
  68.         return 'ComWrapper<{}>'.format(repr(self._wrapped_object))
  69.  
  70. # Подключение к AutoCAD осуществляем через объект ComWrapper
  71.  
  72. acad = ComWrapper(win32com.client.dynamic.Dispatch("AutoCAD.Application"))
  73.  

Если задачу удастся решить корректно, обязательно сюда выложу.

upd: похоже, полностью корректное решение найдено. Протестирую - выложу для использования.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: dlobyntsev от 15-04-2022, 16:50:46
Всем доброго дня. Думаю, каждый, кто работает с автокадом из чистого питона, сталкивались с ошибкой -2147418111 "Call was rejected by callee/Вызов был отклонен". Плохой вариант борьбы с данной ошибкой - введение в код задержек. Я реализовал и хороший вариант - перехват ошибок при любом обращении к автокаду. Для удобства собрал модуль pyacadcom. Устанавливается стандартно: pip install pyacadcom.

В вашем скрипте:
Код - Python [Выбрать]
  1. #импортируем модуль
  2. import pyacadcom
  3.  
  4. #создаём объект автокада, результат аналогичен app = win32com.client.dynamic.Dispatch("AutoCAD.Application")
  5. app = pyacadcom.AutoCAD()
  6.  
  7. #Обращаемся к объекту автокада в соответствии с объектной моделью, например
  8. adoc = app.ActiveDocument #получение активного документа автокада
  9.  

При этом все ошибки -2147418111 перехватываются, никаких задержек в коде ставить не нужно.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 15-04-2022, 16:58:43
Думаю, каждый, кто работает с автокадом из чистого питона, сталкивались с ошибкой -2147418111 "Call was rejected bycallee/Вызов был отклонен".
Вообще-то ошибок, связанных с "занятостью" AutoCAD несколько: https://adn-cis.org/kak-ispolzuya-visual-c-zapustit-autocad-i-zastavit-ego-vyipolnyat-nekotoryie-dejstviya.html
Название: Re: Python & ActiveX/COM Autocad
Отправлено: dlobyntsev от 15-04-2022, 17:26:50
Это не ошибка "занятости" автокада. Это ошибка, причиной которой является взаимодействие с COM через модуль pywin32. Не поддерживается очередь команд, и, если новый запрос поступает до отработки предыдущего, новый запрос отклоняется. Для меня это было огромной головной болью, потому что появление этой ошибки зависит отчего угодно, вплоть до фазы Луны. Если посмотреть на вопросы людей в этой теме - явно такие же проблемы. Пока данный модуль решил все вылеты моих скриптов. Спасибо за наводку, на всякий случай включу и эти ошибки в обработчик - это просто.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Derie1 от 15-04-2022, 17:45:29
Для удобства собрал модуль pyacadcom.
Спасибо за наводку. Попробовал в своём скрипте заменить:
Код - Python [Выбрать]
  1. acad = win32com.client.Dispatch("AutoCAD.Application")
  2.  
на строчку из библиотеки:
Код - Python [Выбрать]
  1. acad = pyacadcom.AutoCAD()
  2.  

По результатам теста все равно случаются ошибки, причем в тех же местах что и раньше. Думаю, всё дело в том, что в части функций так и остаются запросы через win32com.client, например, фильтр для создания SelectionSet:
Код - Python [Выбрать]
  1. objSS = doc.SelectionSets.Add("toErase")
  2.  
  3. FilterType = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_I2, [0])
  4. FilterData = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_VARIANT, ['INSERT'])
  5. SELECT_ALL = 5
  6.  
  7. objSS.Select(SELECT_ALL, pythoncom.Empty, pythoncom.Empty, FilterType, FilterData)
  8.  
Так же в задании точки в модели используется:
Код - Python [Выбрать]
  1. def POINT(x, y, z):
  2.     point = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, (x, y, z))
  3.     return point
  4.  
Почему то, при замене этой функции на аналог из pyacadcom:
Код - Python [Выбрать]
  1. def POINT(x, y, z):
  2.     point = pyacadcom.acadPoint(x, y, z)
  3.     return point
  4.  
блок вставляться отказываются, при этом получаю следующую ошибку:
Цитировать
total_blk = ms.InsertBlock(pt1, "TOTAL", 1.0, 1.0, 1.0, 0)
  File "<COMObject <unknown>>", line 3, in InsertBlock
TypeError: must be real number, not acadPoint

Эти проблемы возможно решить с использованием pyacadcom?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: dlobyntsev от 15-04-2022, 17:58:38
objSS = doc.SelectionSets.Add("toErase")
Как получен doc? Если это не производное от pyacadcom.AutoCAD() - ошибки перехватываться не будут. Какой код ошибки?
класс acadPoint в pyacadcom в текущем варианте возвращает координаты в формате, подходящим для автокада при использовании acadPoint.coordinates:
Код - Python [Выбрать]
  1. def POINT(x, y, z):
  2.     point = pyacadcom.acadPoint(x, y, z)
  3.     return point.coordinates
  4.  
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Derie1 от 15-04-2022, 18:04:53
Как получен doc?
Код - Python [Выбрать]
  1. acad = pyacadcom.AutoCAD()
  2. doc = acad.Documents.Open(dwg_file)
  3. ms = doc.ModelSpace
  4.  
Заменил создание точки, так работает, спасибо!
Код - Python [Выбрать]
  1. def POINT(x, y, z):
  2.     return pyacadcom.acadPoint(x, y, z).coordinates
  3.  
Название: Re: Python & ActiveX/COM Autocad
Отправлено: dlobyntsev от 15-04-2022, 18:10:05
acad = pyacadcom.AutoCAD()
doc = acad.Documents.Open(dwg_file)
ms = doc.ModelSpace
Вообще должно работать. Напишите коды ошибок, которые получаются.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Derie1 от 15-04-2022, 21:10:28
Вообще должно работать. Напишите коды ошибок, которые получаются.
На всякий случай, привожу весь скрипт по удалении определенных блоков из чертежа:
Код - Python [Выбрать]
  1. import win32com.client
  2. import pythoncom
  3. from PyQt5 import QtWidgets
  4. import pyacadcom
  5.  
  6.  
  7. app = QtWidgets.QApplication([])
  8. # acad = win32com.client.Dispatch("AutoCAD.Application")
  9. acad = pyacadcom.AutoCAD()
  10. dwg_file = QtWidgets.QFileDialog.getOpenFileName(caption="Выберите файл шаблона или схемы в AutoCAD... ",
  11.                                                  filter="DWG (*.dwg)")[0]  # выбираем исхоный файл
  12. doc = acad.Documents.Open(dwg_file)
  13.  
  14. try:
  15.     for i in doc.SelectionSets:
  16.         i.Delete()
  17. except:
  18.     pass
  19.  
  20. objSS = doc.SelectionSets.Add("blocks")
  21.  
  22. FilterType = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_I2, [0])
  23. FilterData = win32com.client.VARIANT(
  24.     pythoncom.VT_ARRAY | pythoncom.VT_VARIANT, ['INSERT'])
  25. SELECT_ALL = 5
  26.  
  27. objSS.Select(SELECT_ALL, pythoncom.Empty,
  28.              pythoncom.Empty, FilterType, FilterData)
  29. print("\n")
  30.  
  31. for obj in objSS:
  32.     if obj.EffectiveName == "TOTAL" or obj.EffectiveName == "KNF" or obj.EffectiveName == "INCOMER" or obj.EffectiveName == "AUTOMAT" or obj.EffectiveName == "LINE":
  33.         obj.Delete()
  34.  
  35. objSS.Delete()
  36.  

Ошбика 1 (при создании SelSet):
Цитировать
Traceback (most recent call last):
  File "c:\Users\mdavy\Dropbox\MyProg\SLD_Builder\.test_code\deleting_selected_blocks.py", line 20, in <module>
    objSS = doc.SelectionSets.Add("blocks")
  File "C:\Users\mdavy\AppData\Local\Programs\Python\Python310\lib\site-packages\win32com\client\dynamic.py", line 628, in __getattr__
    ret = self._oleobj_.Invoke(retEntry.dispid, 0, invoke_type, 1)
pywintypes.com_error: (-2147418111, 'Вызов был отклонен.', None, None)
Ошибка 2 (там же, но другая):
Цитировать
Traceback (most recent call last):
  File "c:\Users\mdavy\Dropbox\MyProg\SLD_Builder\.test_code\deleting_selected_blocks.py", line 20, in <module>
    objSS = doc.SelectionSets.Add("blocks")
  File "C:\Users\mdavy\AppData\Local\Programs\Python\Python310\lib\site-packages\win32com\client\dynamic.py", line 639, in __getattr__
    raise AttributeError("%s.%s" % (self._username_, attr))
AttributeError: <unknown>.Add
Ошибка 3 (при удалении блоков. Здесь может быть ошибка на любом блоке, часть удалит, а потом где то встрянет. Так же здесь случаются ошибки как и в случае 1):
Цитировать
Traceback (most recent call last):
  File "c:\Users\mdavy\Dropbox\MyProg\SLD_Builder\.test_code\deleting_selected_blocks.py", line 32, in <module>
    if obj.EffectiveName == "TOTAL" or obj.EffectiveName == "KNF" or obj.EffectiveName == "INCOMER" or obj.EffectiveName == "AUTOMAT" or obj.EffectiveName == "LINE":   
  File "C:\Users\mdavy\AppData\Local\Programs\Python\Python310\lib\site-packages\win32com\client\dynamic.py", line 639, in __getattr__
    raise AttributeError("%s.%s" % (self._username_, attr))
AttributeError: <unknown>.EffectiveName
Ошбика 4 (при добавлении всех блоков в SelSet):
Цитировать
Traceback (most recent call last):
  File "c:\Users\mdavy\Dropbox\MyProg\SLD_Builder\.test_code\deleting_selected_blocks.py", line 27, in <module>
    objSS.Select(SELECT_ALL, pythoncom.Empty,
  File "C:\Users\mdavy\AppData\Local\Programs\Python\Python310\lib\site-packages\win32com\client\dynamic.py", line 639, in __getattr__
    raise AttributeError("%s.%s" % (self._username_, attr))
AttributeError: Add.Select

Ну и так далее. При этом у меня на домашнем компе, код намного более стабильно работает, чем на рабочем..
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Алексей Кулик от 15-04-2022, 22:00:10
Derie1, а удаление выполняется только для "обычных" вхождений? А состояние слоев игнорируется специально? А описания блоков удалять не надо?
P.S. Я в питоне как известное животное в известных плодах.
P.P.S. Я бы не стал делать ставку на именованные наборы примитивов.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: dlobyntsev от 15-04-2022, 23:01:12
Ну и так далее. При этом у меня на домашнем компе, код намного более стабильно работает, чем на рабочем..
Пока не получается повторить ошибки. Протестирую на доступных компьютерах, подумаю как сделать диагностику у вас поинформативней и отпишусь.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Derie1 от 15-04-2022, 23:23:34
Derie1, а удаление выполняется только для "обычных" вхождений? А состояние слоев игнорируется специально? А описания блоков удалять не надо?
Не совсем понял, что имеете в виду под "обычными" вхождениями?
Слои, даже не знаю, нужно ли их учитывать. По идее же все равно на слои.
Описания блоков удалять не надо, т.к. потом они же должны вставляться с новыми значениями параметров. Скрипт строит однолинейную схему электрических щитов. Удаление блоков нужно для внесения изменений в ранее созданный щит.
Задумка такая у меня. Вообще скрипт состоит из 2-х больших частей.
1 - открытие файла, удаление всех целевых блоков;
2 - вставка блоков и заполнение текстовых параметров из расчетной таблицы эксель.
Удаление целевых блоков нужно для внесения изменений (изменится может и количество блоков в схеме, поэтому, никак кроме как удаление всех элементов и вставка по новой с заполнением параметров не знаю как это сделать).

Протестирую на доступных компьютерах, подумаю как сделать диагностику у вас поинформативней и отпишусь.
Вот ссылка (https://github.com/Derie1/SLD_Builder.git) на мой GitHub по этому скрипту. Там в подпапке test_files есть файл SLD_full.dwg. На нем можно протестировать удаление блоков этих.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: dlobyntsev от 15-04-2022, 23:32:16
Вот ссылка на мой GitHub по этому скрипту. Там в подпапке test_files есть файл SLD_full.dwg
Ничто не ново под луной. Аналогичную штуку написал лет 5 назад :)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Алексей Кулик от 16-04-2022, 09:02:08
Я про то, что обрабатывать вхождения блоков внутрь других блоков не надо?
Если заранее известно, что надо обрабатывать только пространство модели, то почему бы не получить указатель именно на него и проходить по нему? Без создания / удаления именованных наборов.
Примерно так:
Код - Python [Выбрать]
  1. app = QtWidgets.QApplication([])
  2. # acad = win32com.client.Dispatch("AutoCAD.Application")
  3. acad = pyacadcom.AutoCAD()
  4. dwg_file = QtWidgets.QFileDialog.getOpenFileName(caption="Выберите файл шаблона или схемы в AutoCAD... ",
  5.                                                  filter="DWG (*.dwg)")[0]  # выбираем исхоный файл
  6. doc = acad.Documents.Open(dwg_file)
  7. for obj in doc.ModelSpace:
  8.     if obj.ObjecName="AcDbBlockReference" and (obj.EffectiveName == "TOTAL" or obj.EffectiveName == "KNF" or obj.EffectiveName == "INCOMER" or obj.EffectiveName == "AUTOMAT" or obj.EffectiveName == "LINE"):
  9.         obj.Delete()
  10.  
Касаемо слоев - если блок вдруг окажется на заблокированном / замороженном слое, удалить его не получится подобным образом.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Derie1 от 19-04-2022, 12:06:53
Примерно так:
Ваш вариант имеет место быть. Он работает, но у него все те же проблемы. Периодически, рандомно, вылетают ошибки типа "pywintypes.com_error: (-2147418111, 'Вызов был отклонен.', None, None)"

А я вот подумал, а нельзя ли при создании SelectionSet в фильтр прописать не просто все блоки в файле, а все блоки с определенным именем, после чего просто стереть все элементы сета через Erase()? Или сперва сделать сет со всеми блоками, а потом их перебрать и блоки с нужными именами закинуть в другой сет и потом его целиком удалить.
Такой подход сократит количество обращений к автокаду, а соответственно, сократит количество возможных ошибок этих.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Алексей Кулик от 19-04-2022, 12:22:56
При таком подходе не удастся получить вхождения динамических блоков.
В одном из чатов мелькнуло (цитирую):
"Добрый день, коллеги.
Думаю, все сталкивались с ошибкой -2147418111 "Call was rejected by callee"/"Вызов был отклонен" при работе с кадом из чистого питона. Удалось решить проблему. Для удобства оформил модуль pyacadcom. Устанавливается стандартно через pip.
В коде нужно импортировать модуль и создать объект:
import pyacadcom
acad = pyacadcom.AutoCAD()
Дальше все как обычно согласно объектной модели автокад."
Что это, с чем его едят и как устанавливают - лично я без понятия. Может, и сработает?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Derie1 от 19-04-2022, 12:28:55
Алексей Кулик,
Да, я перешел на этот модуль, но все равно ошибки случаются...
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Алексей Кулик от 19-04-2022, 12:34:18
Ну тогда сорри, дальше идей нет :(
Название: Re: Python & ActiveX/COM Autocad
Отправлено: dlobyntsev от 19-04-2022, 14:15:20
Алексей Кулик,
Да, я перешел на этот модуль, но все равно ошибки случаются...
Модуль допилим :)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Derie1 от 20-04-2022, 09:38:23
Модуль допилим :)

Огромное спасибо, dlobyntsev!

После пары обновлений модуля pyacadcom ошибки пропали. Конечно, я продолжу тестировать, и распространю свой скрипт среди коллег - тоже будут тесты. Но пока в версии модуля 0.0.9 ошибок не наблюдается. Огромное спасибо dlobyntsev!

Просто обращаемся к Автокаду через модуль, а дальше все как обычно:
Код - Python [Выбрать]
  1. import pyacadcom
  2.  
  3. acad = pyacadcom.AutoCAD()
Название: Re: Python & ActiveX/COM Autocad
Отправлено: choppylion от 22-04-2022, 13:36:32
Добрый день. Возникла проблема с копированием описания динамического блока из одного документа в другой — после "вставки" описания блока, он перестает быть динамическим.

Код скрипта:
Код - Python [Выбрать]
  1. src_obj = src_doc.Blocks.Item(block_name)
  2. print("Src:", src_obj.IsDynamicBlock)
  3.  
  4. src_obj_array = ARRAY(src_obj)
  5. insertion_point = POINT(src_obj.Origin)
  6. name = src_obj.Name
  7.  
  8. new_block = dst_doc.Blocks.Add(insertion_point, name)
  9. src_doc.CopyObjects(src_obj_array, new_block)
  10. print("New:", new_block.IsDynamicBlock)

И на выходе соответственно получаю:
Код - Python [Выбрать]
  1. Src: True
  2. New: False

Подскажите, пожалуйста, каким же образом правильно копировать динамические блоки? Со статическими проблем не было, и данного кода хватало
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Алексей Кулик от 22-04-2022, 13:38:37
А в питоне нет метода CopyObjects ?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: choppylion от 22-04-2022, 15:37:10
А в питоне нет метода CopyObjects ?
А какой встроенный питоновский метод вы имеете в виду?
Я пользуюсь методом CopyObjects объекта типа Document: https://help.autodesk.com/view/OARX/2019/ENU/?guid=GUID-D9E0A89C-2D81-4141-8B88-B9AC6EAABD62 (https://help.autodesk.com/view/OARX/2019/ENU/?guid=GUID-D9E0A89C-2D81-4141-8B88-B9AC6EAABD62)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Алексей Кулик от 22-04-2022, 15:45:43
А, сорри, не увидел сначала. Мне кажется, что копируется вхождение блока, а надо копировать описание. На лиспе-то я напишу, а вот на питоне - увы и ах.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 22-04-2022, 17:26:47
choppylion,
Вместо
Код - Python [Выбрать]
  1. src_doc.CopyObjects(src_obj_array, new_block)
должно быть
Код - Python [Выбрать]
  1. src_doc.CopyObjects(src_obj_array, dst_doc.Blocks)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: choppylion от 23-04-2022, 21:08:29
choppylion,
Вместо
Код - Python [Выбрать]
  1. src_doc.CopyObjects(src_obj_array, new_block)
должно быть
Код - Python [Выбрать]
  1. src_doc.CopyObjects(src_obj_array, dst_doc.Blocks)
Пробовал так. Код успешно отрабатывает, но блок так и не появляется среди доступных в панели Insert.

Но обнаружил интересную вещь: мой изначальный блок состоит из 6 отдельных объектов, все они передаются в функцию CopyObjects как один блок в таком виде:
Код - Python [Выбрать]
  1. win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_DISPATCH, block)

и CopyObjects возвращает мне не 1 блок, как я ожидаю, а 6 отдельных объектов:
Цитировать
result = {tuple: 6} (<COMObject CopyObjects>, <COMObject CopyObjects>, <COMObject CopyObjects>, <COMObject CopyObjects>, <COMObject CopyObjects>, <COMObject CopyObjects>)
 0 = {CDispatch} <COMObject CopyObjects>
 1 = {CDispatch} <COMObject CopyObjects>
 2 = {CDispatch} <COMObject CopyObjects>
 3 = {CDispatch} <COMObject CopyObjects>
 4 = {CDispatch} <COMObject CopyObjects>
 5 = {CDispatch} <COMObject CopyObjects>

Может быть, я как-то не так "подготавливаю" свой динамический блок для копирования, что он потом распадается на составные объекты?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 23-04-2022, 21:49:43
new_block = dst_doc.Blocks.Add(insertion_point, name)
Этого быть не должно. Иначе ты сразу создаешь блок, который неможет быть динамическим.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: choppylion от 23-04-2022, 22:35:49
Танцы с бубном вокруг Array не привели к успеху — Автокад жаловался на некорректный размер массива.
Проблема была в том, что при передаче описания блока с составными объектами через Array в CopyObjects, сама сущность блока терялась, и передавались уже его внутренние объекты.

Удалось костыльно пофиксить следующим образом: создаем в исходном документе еще один блок, в который включаем референс нужного нам блока.
Если "запаковать" исходный блок в еще один блок упомянутым способом, то при его распаковке для передачи в CopyObjects уже остается нужный нам исходный блок, который успешно появляется в меню Insert.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Шашлык от 25-05-2022, 03:19:04
Всем привет!
Никто не сталкивался выбором одного из запущенных экземпляров autocad?
Если в автокаде включена настройка, что при запуске файла запускается новый экземпляр автокада, есть ли возможность подключится к нужному мне экземпляру? То есть это не новый документ открывается в уже созданном, а именно новый процесс.
 
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 25-05-2022, 08:54:50
Шашлык,
Если вкратце, то возможности выбрать один из запущенных экземпляров одной и той же версии AutoCAD нет.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Yn.rza от 06-08-2022, 19:40:51
Здравствуйте, я новичок в этой теме и очень прошу помочь с следующей проблемой. У блоков которые я использую в чертежах есть свойство "Отраженное состояние", которое получается прочитать, но при попытке изменить - ошибка, хотя разрешенные состояния "AllowedValues" выводятся как int ноль и единица
Код - Python [Выбрать]
  1. def selection_user():
  2.         try:
  3.             cad.ActiveDocument.SelectionSets.Item("SS1").Delete()
  4.         except Exception:
  5.             logger.debug('Delete selection failed')
  6.         selection = cad.ActiveDocument.SelectionSets.Add('SS1')
  7.         selection.SelectOnScreen(FilterType, FilterData)
  8.         return selection
  9. ssget = selection_user()
  10. #print(ssget.Count)
  11. for obj in ssget:
  12.     if obj.EffectiveName == "KLEMMA_1":
  13.          prop = obj.GetDynamicBlockProperties()
  14.          prop[3].Value = 1

com_error: (-2147352567, 'Ошибка.', (0, 'AutoCAD.Application', 'Неверный ввод', 'C:\\Program Files\\Autodesk\\AutoCAD 2017\\HELP\\OLE_ERR.CHM', -2145386493, -2145386493), None)
проблем с изменением других свойств блоков нет
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 06-08-2022, 19:46:11
Yn.rza,
А какие значения у FilterType и FilterData?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Yn.rza от 06-08-2022, 19:51:10
Код - Python [Выбрать]
  1. FilterType = [0]
  2. FilterData = ["INSERT"]
  3. FilterType = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_I2, FilterType)
  4. FilterData = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_VARIANT, FilterData)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 06-08-2022, 19:53:59
Yn.rza,
Новый вопрос. А какое значение у prop[3].Value перед тем, как ты пытаешься его изменить?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Yn.rza от 06-08-2022, 20:13:00
у него значение 0,
Отраженное состояние = Без отражения - это в автокаде в панеле свойств блока

Код - Python [Выбрать]
  1. print(prop[3].PropertyName, prop[3].Value)
  2. print(type(prop[3].Value))
  3. print(prop[3].AllowedValues)
  4. print(prop[3].ReadOnly)
дает следующее:

Отраженное состояние 0
<class 'int'>
(0, 1)
False
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 06-08-2022, 20:18:58
у него значение 0,
Я правильно понимаю, что ты распечатал это значение и убедился, что оно 0?
У DynamicBlockReferenceProperty значение должно быть типа Variant (смотри документацию). Так что думаю, что должно быть как-то так:
Код - Python [Выбрать]
  1. prop[3].Value = win32com.client.VARIANT(pythoncom.VT_I2, 1)
Возможно вместо pythoncom.VT_I2 должно быть pythoncom.VT_I4
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Yn.rza от 06-08-2022, 20:52:57
Спасибо огромное, так работает!
а я до этого пробовал
prop[3].Value = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_I2, [1])
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 06-08-2022, 20:55:45
а я до этого пробовал
prop[3].Value = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_I2, [1])
Пытался массив подсунуть? ;)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Yn.rza от 06-08-2022, 20:58:44
получается да, по аналогии с FilterType
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Xenocephal от 16-09-2022, 14:16:59
Здравствуйте,

Подскажите пожалуйста, кто-нибудь сталкивался с ситуацией когда Block при обращении к методу GetBoundingBox выдает ошибку?
(https://i.postimg.cc/kRCqZJ4m/2022-09-16-140838.jpg) (https://postimg.cc/kRCqZJ4m)

Эта же ошибка вылезает в 4 чертежах из 203, в остальных все нормально обрабатывается.
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 16-09-2022, 14:25:55
Да. Такое бывает. Обычно это связано с пустыми текстами, отрезками нулевой длины и т.д. Но судя по коду ошибки удален какой то объект, который участвует в подсчете габаритов блока. На всякий случай проверьте чертеж на ошибки (команда _AUDIT)
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Xenocephal от 16-09-2022, 14:29:53
Да. Такое бывает. Обычно это связано с пустыми текстами, отрезками нулевой длины и т.д. Но судя по коду ошибки удален какой то объект, который участвует в подсчете габаритов блока. На всякий случай проверьте чертеж на ошибки (команда _AUDIT)
Здорово! Помогло, теперь корректно считается. Искренне благодарю!
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Александр Ривилис от 16-09-2022, 22:36:07
Помогло, теперь корректно считается.
После _AUDIT?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: Xenocephal от 16-09-2022, 23:12:27
Помогло, теперь корректно считается.
После _AUDIT?

Да. Вставил после обработки исключения doc.AuditInfo(True) и метод блока корректно заработал (без исправления ошибок не пробовал).
Название: Re: Python & ActiveX/COM Autocad
Отправлено: a.green от 04-10-2022, 14:56:43
Здравствуйте, Коллеги!
Подскажите пожалуйста, как добраться до списка кастомных свойств DWG с помощью стандартного Пайтона?
Количество полей без проблем получается с помощью doc.SummaryInfo.NumCustomInfo(), а вот дальше, как бы я не пытался получить значения, хоть по индексу, хоть по ключу, я их не получаю.
Нагуглил, что перед тем, как получить значение с помощью SummaryInfo.GetCustomByIndex() или SummaryInfo.GetCustomByKey(), нужно правильно инициализировать под него буфер.
Нашел даже пример https://www.autohotkey.com/boards/viewtopic.php?f=76&t=66491&sid=d5613bd70eab094f314c5216eb141b16 (https://www.autohotkey.com/boards/viewtopic.php?f=76&t=66491&sid=d5613bd70eab094f314c5216eb141b16) с кодом, который должен работать. Но так и не смог его адаптировать, при том, что константы VT_BYREF и VT_BSTR в pythoncom есть.
Может быть кто-то из вас уже решал эту задачу?
Название: Re: Python & ActiveX/COM Autocad
Отправлено: MaxMarsh от 02-12-2022, 16:54:50
Добрый день.

Подскажите пожалуйста как включить у MText свойство Text Frame или Рамка текста.

Обгуглил уже весь интернет, перевел всю встренную документацию, никак не могу разобраться. Дайте, пожалуйста, хоть ссылку на использование.

В соседней теме нашел только метод или свойство ShowBorders, но ни как использовать, ни аттрибутов ничего кроме этого выражения.

Заранее благодарен.