Как присвоить идентификатор к конкретному объекту из множественного выбора на VBA
| Правила | Регистрация | Пользователи | Сообщения за день |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Как присвоить идентификатор к конкретному объекту из множественного выбора на VBA

Как присвоить идентификатор к конкретному объекту из множественного выбора на VBA

Ответ
Поиск в этой теме
Непрочитано 14.11.2024, 10:34 #1
Как присвоить идентификатор к конкретному объекту из множественного выбора на VBA
posetitel
 
Регистрация: 16.10.2013
Сообщений: 395

Товарищи, подскажите.
Сейчас опишу проблему развернуто.
Общая задача такая: необходимо сравнить вершину каждой полилинии чертежа с другими вершинами полилиний и если эти вершины расположены близко, то совместить.
Алгоритм решения вижу такой:
1) в коде делаю выбор всех полилиний в модели,
2) далее организовываю цикл вида for each (т.е. для каждого выбранного примитива).
3) в теле этого цикла хочу каждой полилинии присвоить свой так называемый идентификатор, распространяющийся только внутри цикла, не приписывающий внешних данных или иной информации к полилиниям в чертеже,
4) потом на основании идентификатора работать с каждой конкретной полилинией сравнивая их друг с другом.
Вот как сделать пункт 3?
Понимаю, что решение общей задачи может быть и не таким, как расписал ниже, подсказки как лучше решить тоже приветствую, но важнее понять пункт 3, как работать с конкретным объектом из выбора.
Просмотров: 1150
 
Непрочитано 14.11.2024, 11:23
#2
name02


 
Регистрация: 10.01.2020
Сообщений: 415


Не понял - для чего же нужен идентификатор?
Сравнивать координаты вершин полилиний с вершинами какой-то "главной" полилинии?
name02 вне форума  
 
Автор темы   Непрочитано 14.11.2024, 11:27
#3
posetitel


 
Регистрация: 16.10.2013
Сообщений: 395


Идентификатор нужен чтобы потом работать с конкретной полилинией, а не набором.
Например, выбрать сначала одну эталонную, все остальные с ней сравнить, потом больше эту эталонную не трогать, а работать с другими, среди других выбрать еще одну эталонную, а та первая уже не должна участвовать в наборе и чтобы исключить ее из набора, думаю делать это по идентификатору.
posetitel вне форума  
 
Непрочитано 14.11.2024, 11:28
#4
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 40,402


Если уж с указателями на полилинии работать не хочется, чем не нравится тот же хендл?
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 14.11.2024, 11:31
#5
trir


 
Регистрация: 18.12.2010
Сообщений: 5,107


всё не так
trir вне форума  
 
Автор темы   Непрочитано 14.11.2024, 11:34
#6
posetitel


 
Регистрация: 16.10.2013
Сообщений: 395


Что за указатели полилиний? Это которые руками (мышкой) надо тыкать в модели? Если есть программные, то где про него почитать?
И где почитать про хэндл?

ПС. В сообщении написал про полилинии, потому что просто пока это насущная задача, но потом аналогичным образом планирую работать с другими наборами, например, мультивыноски, блоки и т.д. Подход одинаковый: в наборе присвоить каждому свой идентификатор, чтобы получить некий именованный массив элементов и потом по номеру элемента работать с объектом соответствующего номера.
posetitel вне форума  
 
Непрочитано 14.11.2024, 11:39
#7
name02


 
Регистрация: 10.01.2020
Сообщений: 415


Цитата:
Сообщение от posetitel Посмотреть сообщение
1) в коде делаю выбор всех полилиний в модели,
Если выбрать все полилинии програмно, то они помещаются в набор в известном только автокаду порядке (т.е. порядок их следования в наборе не будет определяться ни длиной, ни расположением слева направо или сверху вниз в пространстве модели).
Тебе самому надо будет решить какая из них будет "главной".
Посмотри - в автокаде отдельно выделил "главную", отдельно остальные. Прошелся по остальным на всякий чтобы убрать случайно попавшую "главную"
И затем сравниваешь полилинии из второго набора с вершинами "главной"
name02 вне форума  
 
Автор темы   Непрочитано 14.11.2024, 11:41
#8
posetitel


 
Регистрация: 16.10.2013
Сообщений: 395


Цитата:
Сообщение от name02 Посмотреть сообщение
Если выбрать все полилинии програмно, то они помещаются в набор в известном только автокаду порядке (т.е. порядок их следования в наборе не будет определяться ни длиной, ни расположением слева направо или сверху вниз в пространстве модели).
Тебе самому надо будет решить какая из них будет "главной".
Посмотри - в автокаде отдельно выделил "главную", отдельно остальные. Прошелся по остальным на всякий чтобы убрать случайно попавшую "главную"
И затем сравниваешь полилинии из второго набора с вершинами "главной"
Я понимаю, что в набор они попадают в рандомном порядке. Поэтому и хочу далее работать с этим набором как с массивом.
Т.е. хочу сравнить с первой линией все остальные, далее первую линию исключить из набора и сравнивать оставшиеся со второй и т.д. Не важно какая будет первая, важно, что в следующих итерациях она уже не участвует, а исключаю ее из дальнейшего набора по идентификатору (индексу элемента в массиве, например)
posetitel вне форума  
 
Непрочитано 14.11.2024, 12:26
1 | #9
name02


 
Регистрация: 10.01.2020
Сообщений: 415


Не понимаю проблемы:
1 Получил набор объектов SelSet
2 Взял первый объект из набора Set PL = SelSet.Item(0)
3 Удалил из набора этот объект SelSet.Item(0).Delete
4 Проходишь объекты из SelSet и сравниваешь его с объектом PL
name02 вне форума  
 
Автор темы   Непрочитано 14.11.2024, 12:41
#10
posetitel


 
Регистрация: 16.10.2013
Сообщений: 395


О! про SelSet.Item(0) был не в курсе. Опробую.
posetitel вне форума  
 
Непрочитано 14.11.2024, 13:08
1 | #11
Нубий-IV

Инженер-философ
 
Регистрация: 24.04.2019
Хабаровск
Сообщений: 2,069


Насколько я понимаю, этот алгоритм сравнит каждую точку с каждой, и сложность имеет O(n!). Скорее всего, он будет вешаться, начиная с нескольких десятков полилиний. Подозреваю, что для обработки больших чертежей нужно что-то, что быстро ищет в 3D-пространстве (или в 2D, если чертеж плоский). Например, завести KD-дерево или R-дерево, и при обходе полилиний, для каждой точки, если близкая есть в дереве - округлять, если нет - добавлять в дерево. Реализации можно погуглить. У таких деревьев скорость поиска вроде логарифмическая, а не факториальная.
Нубий-IV вне форума  
 
Автор темы   Непрочитано 14.11.2024, 13:54
#12
posetitel


 
Регистрация: 16.10.2013
Сообщений: 395


Цитата:
Сообщение от name02 Посмотреть сообщение
Не понимаю проблемы:
1 Получил набор объектов SelSet
2 Взял первый объект из набора Set PL = SelSet.Item(0)
3 Удалил из набора этот объект SelSet.Item(0).Delete
4 Проходишь объекты из SelSet и сравниваешь его с объектом PL
После команды SelSet.Item(0).Delete нумерация объектов в выборе не сместится? Т.е. если я после операции SelSet.Item(0).Delete выполню Set PL1 = SelSet.Item(0), то PL1 определится или вылетит ошибка?
Ну и теоретически таким образом нельзя ли самому массив сформировать вроде
Set PL0 = SelSet.Item(0)
Set PL1 = SelSet.Item(1)
Set PL2 = SelSet.Item(2) и т.д.?

Нубий-IV, попробую нагуглить эти деревья...
posetitel вне форума  
 
Непрочитано 14.11.2024, 14:11
1 | #13
name02


 
Регистрация: 10.01.2020
Сообщений: 415


Ты попробуй сам удали и посмотри - быстрее и легче запомнишь.
Зачем тебе массивы формировать? Сейчас у тебя 10 линий, потом 800 - будешь думать как задать массив нужного размера.
Работай с набором SelectionSet, по нему проходи:
Dim oPolyLine as AcadPolyline
For Each oPolyLine In SelSet
<< Делаешь что тебе нужно >>
Next oPolyLine
name02 вне форума  
 
Непрочитано 15.11.2024, 05:03
1 | #14
gumel


 
Регистрация: 20.04.2011
Сообщений: 478


Ну так-то у каждого объекта и так имеется свой индекс.

пример кода (правда на другом языке, но смысл думаю будет ясен):

Код:
[Выделить все]
 
...
  MSpace := Acad.ActiveDocument.ModelSpace; // область модели
  cnt := MSpace.Count; // количество всех объектов
  for i := 0 to cnt - 1 do
    begin
       if MSpace.Item(i).ObjectName = 'AcDbPolyline' then
        begin
          AcPolyLine := MSpace.Item(i);  // указатель на полилинию с индексом i
          ....
        end;
    end;
...
Ну и конечно нет необходимости делать цикл по всем объектам в области модели, наверняка можно пробежаться только по тем, которые выбрал пользователь.
Ну на насчет оптимизации (чтоб программа не вешалась от десятка полилиний), возможно можно будет отсеять лишние полилинии, проверив их габариты с помощью GetBoundingBox (тут сложно сказать не зная специфики задачи)
gumel вне форума  
 
Автор темы   Непрочитано 15.11.2024, 09:20
#15
posetitel


 
Регистрация: 16.10.2013
Сообщений: 395


Парни, всем отписавшимся прожимаю "спасибо", все сообщения читаю, они важны для моего понимания ВБА.
gumel, конечно, не обязательно использовать все объекты модели, проще предварительно выполнить выбор путем SelSet.
Получается, смысла в отдельной операции присвоения идентификатора нет, можно организовать цикл внутри цикла по индексам из выбора.
В первом цикле перебирать полилинии из выбора, а во втором цикле вершины. Что-то вроде такого (даже четыре цикла будет):
Код:
[Выделить все]
cnt1 := SelSet.Count // количество выбранных полилиний
  for i := 0 to cnt1 - 2 do  // цикл прохода по выбранным полилиниям
    AcPolyLine1 := SelSet.Item(i)  
    cnt2 := AcPolyLine1.Count // количество вершин в полилинии i
       for j := 0 to cnt2 - 1 do  // цикл прохода по вершинам первой полилинии из цикла
         for k := i+1 to cnt1 - 1 do  // цикл прохода по оставшимся полилиниям 
         AcPolyLine2 := SelSet.Item(k)  
         cnt3 := AcPolyLine2.Count // количество вершин в полилинии k     
             for l :=0 to cnt3 - 1 do  // цикл сравнения координат оставшихся полилиний с первой полилинией
                  "условие если координата l полилинии k близка к координате j полилинии i то переприсвоить координату, иначе ничего не делать
             next 
           next             
       next
  next
смысл быстро написанного моего кода в том, что первый цикл пробегает по всем линиям с первой до предпоследней (по последней нет смысла пробегать), вложенный цикл пробегает по всем вершинам полилинии i в цикле, следующий цикл пробегает по всем оставшимся полилиниям, четвертый цикл пробегает по каждуй вершине оставшихся полилиний и условие внутри цикла сравнения близости вершин.
posetitel вне форума  
 
Непрочитано 15.11.2024, 09:31
1 | #16
Сергей812


 
Регистрация: 10.08.2013
Сообщений: 11,499


Цитата:
Сообщение от posetitel Посмотреть сообщение
Получается, смысла в отдельной операции присвоения идентификатора нет,
каждый объект в БД чертежа *.dwg и так имеет свой уникальный хэндл (Handle). Хэндл - это в настоящее время 8-байтовое целое число и для каждого нового объекта чертежа просто берется следующее значение этого числа (это самый дешевый по затратам ресурсов способ обеспечить уникальность значения хэндла в пределах чертежа). В VBA хэндл доступен в виде строки и по этой строке через метод HandleToObject можно получить сам объект чертежа.
Сергей812 вне форума  
 
Непрочитано 15.11.2024, 09:55
1 | #17
name02


 
Регистрация: 10.01.2020
Сообщений: 415


Цитата:
Сообщение от posetitel Посмотреть сообщение
В первом цикле перебирать полилинии из выбора, а во втором цикле вершины
Учти, что у разных типов полилиний разное количество координат у вершин https://vbamodel.narod.ru/AutoCAD/idh_coordinates.htm
name02 вне форума  
 
Непрочитано 15.11.2024, 10:10
1 | #18
Нубий-IV

Инженер-философ
 
Регистрация: 24.04.2019
Хабаровск
Сообщений: 2,069


Цитата:
Сообщение от posetitel Посмотреть сообщение
можно организовать цикл внутри цикла по индексам из выбора.
На первый взгляд - то, что нужно. Я, кстати, выше затупил - тут квадратичная сложность, а не факториальная. Так что на реальном чертеже тормозить не должно, если только это не векторизованный генплан.
Нубий-IV вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Как присвоить идентификатор к конкретному объекту из множественного выбора на VBA



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как создать макрос в Autocad2017 для выбора нескольких команд к одному и тому же объекту exlu2732 LISP 6 23.08.2024 11:51
Как в блоке сделать зависимость таблицы выбора от атрибута с полем? (ACAD22) Whaleofthesimon Динамические блоки 0 24.01.2022 12:20
Не отображается ручка выбора Bogich AutoCAD 7 09.07.2014 11:00
Не работают привязки к конкретному объекту чертежа. KronSerg AutoCAD 6 21.03.2011 22:34