Python & ActiveX/COM Autocad

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

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

Оффлайн vxv

  • ADN OPEN
  • Сообщений: 5
  • Карма: 0
Re: Python & ActiveX/COM Autocad
« Ответ #345 : 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]))

Но не пойму как это запустить.
Помогите создать штриховку с указанием внешних и внутренних границ пожалуйста???

Оффлайн Electric

  • ADN OPEN
  • **
  • Сообщений: 53
  • Карма: 6
Re: Python & ActiveX/COM Autocad
« Ответ #346 : 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)

Пока нереализовано...

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

  • Administrator
  • *****
  • Сообщений: 11717
  • Карма: 1524
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Python & ActiveX/COM Autocad
« Ответ #347 : 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)


Пока нереализовано...
Так и должно быть. Каждый из контуров - это один замкнутый контур. А у тебя две окружности. Т.е. одна должна быть внутренним контуром, а вторая наружным.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 11717
  • Карма: 1524
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Python & ActiveX/COM Autocad
« Ответ #348 : 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()

Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 11717
  • Карма: 1524
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Python & ActiveX/COM Autocad
« Ответ #349 : 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.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн vxv

  • ADN OPEN
  • Сообщений: 5
  • Карма: 0
Re: Python & ActiveX/COM Autocad
« Ответ #350 : 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
 :) :) :) :) :) :) :)

Оффлайн vxv

  • ADN OPEN
  • Сообщений: 5
  • Карма: 0
Re: Python & ActiveX/COM Autocad
« Ответ #351 : 12-09-2020, 09:56:15 »
Комплект чертежей состоит из нескольких листов. Мы их обрамляем рамками, у которых есть свой штамп и другое. Эти листы мы располагаем в пространстве модели друг за другом. И на каждом из них может присутствовать какой-то элемент в определенном месте относительно глобальных координат. Можно конечно каждый раз переносить начало координат в нужную нам точку пространства, но думаю есть проектировщики, для кого это критично и недопустипо, да и выглядеть это будет не совсем удобно.
Внимание, а теперь вопрос к знатокам: "Как перед выполнением скрипта отправить запрос в Autocad об указании точки вставки результатов действий скрипта???" Другими словами - указать начало координат для скрипта не (0,0,0), а место куда укажем мышкой. Либо координаты того или иного элемента, который мы выделим мышкой. Думаю такая тема будет много кому полезна. Заранее спасибо и хорошего настроения всем...

Оффлайн Electric

  • ADN OPEN
  • **
  • Сообщений: 53
  • Карма: 6
Re: Python & ActiveX/COM Autocad
« Ответ #352 : 12-09-2020, 12:10:27 »
Комплект чертежей состоит из нескольких листов. Мы их обрамляем рамками, у которых есть свой штамп и другое. Эти листы мы располагаем в пространстве модели друг за другом. И на каждом из них может присутствовать какой-то элемент в определенном месте относительно глобальных координат. Можно конечно каждый раз переносить начало координат в нужную нам точку пространства, но думаю есть проектировщики, для кого это критично и недопустипо, да и выглядеть это будет не совсем удобно.

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

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

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

Код - Python [Выбрать]
  1. point = aDoc.Utility.GetPoint(cc(0, 0, 0), "Укажите точку вставки:")

Оффлайн vxv

  • ADN OPEN
  • Сообщений: 5
  • Карма: 0
Re: Python & ActiveX/COM Autocad
« Ответ #353 : 12-09-2020, 16:24:01 »
Electric, щас доберусь до компа попробую эту строчку. Просто пока не забыл хочу поздравить всех с днём програмиста. Ееееехххххууууу ;D ;D ;D ;D

Оффлайн vxv

  • ADN OPEN
  • Сообщений: 5
  • Карма: 0
Re: Python & ActiveX/COM Autocad
« Ответ #354 : 12-09-2020, 16:53:50 »
Electric, эта строчка то что нужно, работает на ура. Спасибо большое.

Оффлайн DMuzer

  • ADN OPEN
  • ***
  • Сообщений: 132
  • Карма: 2
Re: Python & ActiveX/COM Autocad
« Ответ #355 : 12-10-2020, 06:52:36 »
Огромная просьба, кто знает, подскажите.

Написано большое количество скриптов на питоне для AutoCad. Внезапно Автокад начал глючить вот в каком плане: при обращении к COM функциям они очень часто стали заканчиваться с ошибкой "Вызов был отклонен". Раньше такое в основном случалось, если во время работы скрипта введешь команду или ткнешь мышкой в чертеж, ну и очень редко, по другим причинам типа автосохранения или еще чего то, но это еще чего то было настолько редким, что в принципе можно было не обращать внимания. Сейчас же такое происходит через раз. Скрипты становятся неработоспособными, потому что вызовов много и если на каком то из них прерывается, то весь скрипт надо перезапускать,  или еще хуже, убирать то что наделал незаконченный скрипт.
В общем проблема серьезная. Понимаю, что можно перед каждым вызовом функции делать проверки, но это не выход: во первых такая ерунда может произойти даже при обращении к свойствам объекта, а каждую такую строчку проверять - как бы уже бредом попахивает.
В общем есть ли у кого мысли что могло произойти с автокадом? Как это можно попробовать исправить? Простую переустановку я сделал, не помогло...

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

  • Administrator
  • *****
  • Сообщений: 11717
  • Карма: 1524
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Python & ActiveX/COM Autocad
« Ответ #356 : 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
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн DMuzer

  • ADN OPEN
  • ***
  • Сообщений: 132
  • Карма: 2
Re: Python & ActiveX/COM Autocad
« Ответ #357 : 12-10-2020, 12:23:04 »
Скажем там, несколько дней назад такой проблемы не было точно... Все работало нормально.
Во вторых - проблема то возникает не только при вызове функции, но даже при обращении к свойствам объектов... Ведь каждый раз делать проверки даже при обращении к свойствам - очень сомнительно что это вообще имеет смысл... Скрипты вроде придумали чтобы упрощать жизнь и исключить работу которую можно поручить компьютеру. В таком случае код превращается в проверки проверок перед проверками перед тем как проверить удачно ли прошло обращение к функции или к объекту.

Опять же, раньше то работало и меня все устраивало.

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

  • Administrator
  • *****
  • Сообщений: 11717
  • Карма: 1524
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Python & ActiveX/COM Autocad
« Ответ #358 : 12-10-2020, 12:29:57 »
Опять же, раньше то работало и меня все устраивало.
Если раньше всё работало и AutoCAD не обновлял, то вероятно обновилась Windows. Но вообще-то просто тебе раньше везло. Такая проблема известна как минимум 10 лет. И именно поэтому я не рекомендую использовать COM/ActiveX, а писать приложения, которые грузятся внутрь AutoCAD.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Electric

  • ADN OPEN
  • **
  • Сообщений: 53
  • Карма: 6
Re: Python & ActiveX/COM Autocad
« Ответ #359 : 12-10-2020, 12:33:28 »
Если только все обращения к свойствам объектов обернуть в:

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

Но с графическими построениями такое не прокатит.
Похоже, что кроме изучения C# от такого не избавиться.