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

ADN Club => VBA => Тема начата: Icu от 02-11-2019, 14:07:29

Название: Разорвать СПДС-объекты программно
Отправлено: Icu от 02-11-2019, 14:07:29
Здравствуйте! У меня чертеж с СПДС графикой, версия Civil3D 2016 с СПДС-object enabler'ом, но работать мне нужно в 2019 версии, в которой enabler я не установил, потому что с ним программа становится крайне не стабильной. Чтобы иметь возможность работать с чертежом в 2019 версии, я хочу разорвать все СПДС объекты в 2016 версии. Для этого я хочу выбирать все объекты СПДС и разрывать их по типу explode. Я могу методом простого перебора находить СПДС объекты, но не знаю, как их разрывать. Т.е. я перебираю все объекты в чертеже, могу выделить каждый отдельный объект СПДС, но как разорвать его я не знаю. Подскажите, как можно решить эту задачу? Следующая на подходе задача: проверять все определения блоков в чертеже на наличие СПДС графики, взрывать объекты СПДС и изменять определения блоков.
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Александр Ривилис от 02-11-2019, 14:18:16
Icu,
Проверь есть ли у них метод explode - если есть попробуй воспользоваться им. Если нет, то попробуй через команду Explode.
Кстати, речь идёт об Autodesk SPDS Extenstion или СПДС GraphiCS?
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Icu от 02-11-2019, 14:38:24
Проверь есть ли у них метод explode - если есть попробуй воспользоваться им. Если нет, то попробуй через команду Explode.
Кстати, речь идёт об Autodesk SPDS Extenstion или СПДС GraphiCS?

Я не могу точно сказать, что за enabler у меня установлен. Я перебираю объекты типа Object, метода explode у него нет. А как провернуть эту операцию через команду explode?
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Александр Ривилис от 02-11-2019, 14:40:50
Я перебираю объекты типа Object, метода explode у него нет.
Что для этих объектов возвращает метод ObjectName?
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Александр Ривилис от 02-11-2019, 14:46:15
А как провернуть эту операцию через команду explode?
Как-то так. Для каждого из объектов получаем его метку (свойство Handle) и передаём в эту функцию:
Код - Visual Basic [Выбрать]
  1. Private Sub ExplodeObj(entHandle As String)
  2.     Dim qM As String
  3.     qM = """"
  4.     ThisDrawing.SendCommand "(command " & qM & "_EXPLODE" & qM & " " & "(handent " & qM & entHandle & qM & ")) "
  5.     DoEvents
  6. End Sub
Код не тестировал - перепроверь его.

P.S.: Код исправил по замечанию Icu
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Icu от 02-11-2019, 14:57:13
Что для этих объектов возвращает метод ObjectName?
Возвращает имена с префиксом mcsDbObject.
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Александр Ривилис от 02-11-2019, 14:59:49
Возвращает имена с префиксом mcsDbObject.
Ага. Это объекты СПДС GraphiCS. Уточни у производителя нет ли готовой команды, которая бы расчленяла все их объекты.
Кажется вот эта команда: spexplodeall
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Icu от 02-11-2019, 15:08:30
Возвращает имена с префиксом mcsDbObject.
Ага. Это объекты СПДС GraphiCS. Уточни у производителя нет ли готовой команды, которая бы расчленяла все их объекты.
Кажется вот эта команда: spexplodeall
Суть в том, что обычный _explode прекрасно справляется с этими объектами при выполнении операции руками.
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Icu от 02-11-2019, 15:14:45
А как провернуть эту операцию через команду explode?
Как-то так. Для каждого из объектов получаем его метку (свойство Handle) и передаём в эту функцию:
Код - Visual Basic [Выбрать]
  1. Private Sub ExplodeObj(entHandle As String)
  2.     Dim qM As String
  3.     qM = """"
  4.     ThisDrawing.SendCommand "(command " & qM & "_EXPLODE" & qM & " " & "(handent " & qM & entHandle & qM & "))
  5.    DoEvents
  6. End Sub
Код не тестировал - перепроверь его.
Проверил ваш код. Внёс единственную правку - добавил пробел после финальной скобки перед кавычкой. Работает. Спасибо! Финальный вариант:
Код - Visual Basic [Выбрать]
  1. Private Sub ExplodeObj(entHandle As String)
  2.     Dim qM As String
  3.     qM = """"
  4.     ThisDrawing.SendCommand "(command " & qM & "_EXPLODE" & qM & " " & "(handent " & qM & entHandle & qM & ")) "
  5.     DoEvents
  6. End Sub
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Александр Ривилис от 02-11-2019, 15:18:07
Icu,
Открытый вопрос остаётся с объектами СПДС внутри блоков.
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Icu от 02-11-2019, 15:19:54
Icu,
Открытый вопрос остаётся с объектами СПДС внутри блоков.
Да, с этим буду эксперементировать. Можете дать какую-нибудь наводку? С определениями блоков пока ни разу не сталкивался.
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Александр Ривилис от 02-11-2019, 18:07:11
Icu,
Открытый вопрос остаётся с объектами СПДС внутри блоков.
Да, с этим буду эксперементировать. Можете дать какую-нибудь наводку? С определениями блоков пока ни разу не сталкивался.
Тут боюсь, что командой не обойтись. Нужно анализировать состав всех блоков и если есть объекты СПДС, то входить в редактор блоков расчленять объекты, и закрывать блок с сохранением изменений.
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Icu от 03-11-2019, 18:35:38
Тут боюсь, что командой не обойтись. Нужно анализировать состав всех блоков и если есть объекты СПДС, то входить в редактор блоков расчленять объекты, и закрывать блок с сохранением изменений.
В общем, ситуация такая: могу программно войти в редактор блока, а выйти - уже никак. _blclose работает, только выдавая диалог подтверждения сохранения. Но это не все и не самое главное: способ "подрыва" объектов, использованный ранее, не срабатывает внутри редактора блока. Получаю цепочку сообщений в командной строке:
Цитировать
Команда: (command "_EXPLODE" (handent "87426")) _EXPLODE
Выберите объект: <Неверное имя объекта: E0F94E60>
nil
Выберите объект: *Прервано*
Команда:
Команда: (command "_EXPLODE" (handent "87427")) _EXPLODE
Выберите объект:
Не могу понять, в чем дело.
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Александр Ривилис от 03-11-2019, 18:42:44
Не могу понять, в чем дело.
А как ты получаешь примитивы внутри блока?
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Александр Ривилис от 03-11-2019, 18:50:06
_blclose работает, только выдавая диалог подтверждения сохранения.
Можешь её запускать через lisp:
Код - Auto/Visual Lisp [Выбрать]
  1. (command "_bclose" "_save")
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Александр Ривилис от 03-11-2019, 18:52:02
Когда ты входишь в блок (команда _BEDIT), то блок становится Пространством модели. Соответственно тебе нужно выполнять итерацию не по блоку, а по Пространству модели.
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Icu от 03-11-2019, 18:54:47
А как ты получаешь примитивы внутри блока?
Вот так, сначала проверяю, есть ли нужные мне объекты внутри блока (т.е. спдс или прокси-объекты), затем, если хотя бы один такой объект найден, открываю редактор блока:
Код - Visual Basic [Выбрать]
  1.     For Each item In BlkDef
  2.                 If InStr(item.ObjectName, SPDS_prefix) > 0_
  3.                       Or InStr(item.ObjectName, PROXY_name) > 0 Then
  4.                     Dim comm As String,  command_name As String, block_name As String
  5.                     command_name = "-BEDIT"
  6.                     block_name = BlkDef.Name                  
  7.                     comm = command_name & " " & block_name & vbCrLf                  
  8.                     ThisDrawing.SendCommand comm
  9.                     For Each obj In BlkDef
  10.                       If InStr(item.ObjectName, SPDS_prefix) > 0_
  11.                           Or InStr(item.ObjectName, PROXY_name) > 0 Then ExplodeObj (obj.handle)
  12.                     Next                  
  13.                     ThisDrawing.SendCommand ("_bclose ")    
  14.                   Exit For                          
  15.                 End If          
  16.      Next
  17.  
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Icu от 03-11-2019, 18:55:32
Когда ты входишь в блок (команда _BEDIT), то блок становится Пространством модели. Соответственно тебе нужно выполнять итерацию не по блоку, а по Пространству модели.
Интересная мысль, попробую.
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Александр Ривилис от 03-11-2019, 18:56:03
Icu,
Напоминаю про правило форматирования кода на форуме!
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Александр Ривилис от 03-11-2019, 18:58:16
Icu,
Но вот с анонимными блоками (например, получившимися в результате модификации динамического блока) так не получится, так как имя таких блоков начинается с "*" и _BEDIT их не воспринимает.
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Icu от 03-11-2019, 19:05:20
Соответственно тебе нужно выполнять итерацию не по блоку, а по Пространству модели.
Нет, все равно не получается разорвать спдс. Придется отказаться от блоков, разрывать их сначала, а потом обрабатывать все спдс в чертеже.
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Александр Ривилис от 03-11-2019, 19:10:42
Нет, все равно не получается разорвать спдс.
Что происходит? И если ты вручную запускаешь _EXPLODE внутри блока (т.е. в команде _BEDIT), то объекты СПДС расчленяются? Если нет, то конечно ничего не получится. Если да - то это где-то у тебя в коде ошибка.
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Icu от 03-11-2019, 19:23:51
Что происходит? И если ты вручную запускаешь _EXPLODE внутри блока (т.е. в команде _BEDIT), то объекты СПДС расчленяются? Если нет, то конечно ничего не получится. Если да - то это где-то у тебя в коде ошибка.
Да, вручную все расчленяется хорошо, где ошибка, я пока не могу понять, вызов функции расчленения совершенно тот же, что и выше в коде.
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Александр Ривилис от 03-11-2019, 19:29:15
вызов функции расчленения совершенно тот же, что и выше в коде.
Значит объекты передаёшь не те. Покажи последнее состояние функции. Сразу скажу, что ModelSpace нужно получать уже после ThisDrawing.SendCommand comm (которая вызывает _BEDIT)
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Icu от 03-11-2019, 19:31:02

Значит объекты передаёшь не те. Покажи последнее состояние функции.
Нашел ошибку!!Скопипастил фрагмент кода, а имя переменной-объекта не поменял! Сейчас в роде все расчленяет хорошо, осталось научить правильно закрывать редактор.
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Александр Ривилис от 03-11-2019, 19:32:54
осталось научить правильно закрывать редактор.
Можешь её запускать через lisp:
Код - Auto/Visual Lisp [Выбрать]

    (command "_bclose" "_save")
Так работает. Соответственно на VBA как-то так:
Код - Visual Basic [Выбрать]
  1. ThisDrawing.SendCommand "(command ""_bclose"" ""_save"") "
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Icu от 03-11-2019, 19:45:51
Теперь всё работает, как надо!! Спасибо!
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Icu от 03-11-2019, 19:56:42
Да, лиспы - это сила. Я так предполагаю, что все внутренние команды автокада отрабатываются именно лиспами? Ещё мне стоит рассмотреть вариант вложенных блоков. По сути, Model_Space - это блок, внутри которого могут быть другие блоки, соответственно, намечается повод для рекурсии.
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Александр Ривилис от 03-11-2019, 20:05:31
Я так предполагаю, что все внутренние команды автокада отрабатываются именно лиспами?
Нет. ObjectARX и AutoCAD .NET API.
Ещё мне стоит рассмотреть вариант вложенных блоков.
Это не нужно, если ты пройдёшься просто по таблице блоков (ThisDrawing.Blocks) и проанализируешь/расчленишь СПДС-объекты в каждом из них. Таким образом ты пройдёшься и через ModelSpace и через PaperSpace. Рекурсия не понадобится.
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Icu от 03-11-2019, 20:12:34
Нет. ObjectARX.
Похоже, это следующее, чем я буду овладевать. C++ - очень мощный, гибкий и удобный инструмент. В условиях цейтнота пока бросаюсь на то, что умею - VBA. С++ требует основательного изучения.
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Александр Ривилис от 03-11-2019, 20:14:54
С++ требует основательного изучения.
Рекомендую C# - если не писать профессионально для AutoCAD собственные объекты/примитивы. Для всего остального его достаточно и местами он удобнее.
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Icu от 03-11-2019, 20:18:42
Off-Topic: показать
Рекомендую C# - если не писать профессионально для AutoCAD собственные объекты/примитивы. Для всего остального его достаточно и местами он удобнее.
Так хочется ж профессионально! Подумываю пойти на дистанционные курсы переподготовки, чтобы получить знания и какую-никакую "корочку".
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Александр Ривилис от 03-11-2019, 20:25:09
Off-Topic: показать
Рекомендую C# - если не писать профессионально для AutoCAD собственные объекты/примитивы. Для всего остального его достаточно и местами он удобнее.
Так хочется ж профессионально! Подумываю пойти на дистанционные курсы переподготовки, чтобы получить знания и какую-никакую "корочку".

В моём тексте акцент был не на профессионализм, а на написание собственных объектов/примитивов (Custom Object/Entity). На C# можно писать очень профессионально и некоторые модули в самом AutoCAD написаны на нём.
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Icu от 03-11-2019, 22:48:47
В целом программа работает, но ... мееедленно. Существует ли способ загнать все нужные объекты в какой-нибудь SelectionSet и взорвать их одним разом?
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Александр Ривилис от 03-11-2019, 22:55:18
Существует ли способ загнать все нужные объекты в какой-нибудь SelectionSet и взорвать их одним разом?
Нет. Так не получится, да и врядли будут существенно быстрее. Существенно быстрее будет если переписать с помощью ObjectARX или AutoCAD .NET API
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Icu от 03-11-2019, 22:56:57
да и врядли будут существенно быстрее
Когда руками все выделяю (много раз через qselect), разрыв происходит очень быстро.
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Icu от 04-11-2019, 17:06:38
Как можно взорвать Selection Set на лиспе?
Алгоритм такой: я набираю нужный Selection Set на VBA, потом передаю его в команду на лиспе, чтобы взорвать.
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Александр Ривилис от 04-11-2019, 17:09:08
потом передаю его в команду на лиспе
И как ты его собираешься передать? SelectionSet в lisp прямо передать нельзя. А непрямая передача будет очень не быстрой...
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Icu от 04-11-2019, 17:09:55
И как ты его собираешься передать? SelectionSet в lisp прямо передать нельзя.
Ну, как-нибудь по указателю :)) Типа по handle'у нельзя передать?
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Icu от 04-11-2019, 17:10:41
Как бы их подружить.
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Александр Ривилис от 04-11-2019, 17:11:13
Типа по handle'у нельзя передать?
Так можно передать по одному примитиву. У SelectionSet нет ничего подобного Handle.
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Александр Ривилис от 04-11-2019, 17:12:03
Как бы их подружить.
Не нужно их дружить. Нужно переписать весь алгоритм на lisp, а еще лучше на AutoCAD .NET API.
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Icu от 04-11-2019, 17:13:31
Хорошо, а можно как-то сохранить объекты выделенными после окончания работы макроса? Алгоритм: выбираю объекты в правильный Selection Set, выделяю, затем по окончании макроса взрываю кнопкой _Explode?
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Icu от 04-11-2019, 17:15:24
Типа по handle'у нельзя передать?
Так можно передать по одному примитиву. У SelectionSet нет ничего подобного Handle.
У Selection Set'а есть уникальное имя, его как-то можно использовать.
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Александр Ривилис от 04-11-2019, 17:15:47
Алгоритм: выбираю объекты в правильный Selection Set, выделяю, затем по окончании макроса взрываю кнопкой _Explode?
Нет. Тем более, что ты собираешься это сделать не только с объектами в ModelSpace/PaperSpace, но и в блоках.
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Icu от 04-11-2019, 17:17:00
Алгоритм: выбираю объекты в правильный Selection Set, выделяю, затем по окончании макроса взрываю кнопкой _Explode?
Нет. Тем более, что ты собираешься это сделать не только с объектами в ModelSpace/PaperSpace, но и в блоках.
На блоки я бы временно подзабил :) У меня основная часть СПДС объектов лежит в модели (примерно несколько тысяч), а для блоков хватит и той скорости макроса, которая есть.
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Александр Ривилис от 04-11-2019, 17:19:07
У Selection Set'а есть уникальное имя, его как-то можно использовать.
Теоретически используя расширения VisualLisp это можно сделать, но потом эти все объекты нужно перегонять из SelectionSet в PickSet для использования в команде AutoCAD. Это займёт тоже немалое время.
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Александр Ривилис от 04-11-2019, 17:35:39
У меня основная часть СПДС объектов лежит в модели (примерно несколько тысяч), а для блоков хватит и той скорости макроса, которая есть.
Тогда теоретически для расчленения их всех должно быть достаточно такого lisp-выражения:
Код - Auto/Visual Lisp [Выбрать]
  1. (progn
  2.   (setvar "qaflags" 5)
  3.   (command "_EXPLODE"
  4.     (ssget "_X"
  5.       (list
  6.          (cons 0  "<префикс СПДС*>")
  7.          (cons 410 (getvar "CTAB"))
  8.       )
  9.     )
  10.     ""
  11.   )
  12.   (setvar "qaflags" 0)
  13. )
Только вместо <префикс СПДС*> должно быть правильное значение. Возможно оно SPDS* (нет возможности проверить).
Для того чтобы проверить набери в командной строке AutoCAD, нажми ENTER и выбери СПДС-объект:
Код - Auto/Visual Lisp [Выбрать]
  1. (entget (car (entsel)))
Результат из командной строки сюда.
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Icu от 04-11-2019, 18:47:42
Как правильно воспользоваться этим кодом? С лиспом практически не имел дела.
Название: Re: Разорвать СПДС-объекты программно
Отправлено: Александр Ривилис от 04-11-2019, 20:00:43
Как правильно воспользоваться этим кодом? С лиспом практически не имел дела.
Сохрани в файл с именем spdsexp.lsp и загрузи его при помощи команды _APPLOAD.
Код должен сразу отработать.