Можно конечно и через расширенные данные, НО(!!!) что делать если:
1) один из объектов удалили?
2) один или оба объекта скопировали в пределах чертежа - какие теперь должны быть метки у новых объектов и как их присвоить?
3) один из объектов скопировали в другой чертеж что делать со вторым?
Задача очень сложная и скорее всего средствами AutoCAD .NET API в полном объеме нерешаемая.
Если речь идет не об объектах, а о примитивах, то можно подумать о группах. Но это тоже не полноценное решение, т.к. группы не копируются в другой чертеж как группы и могут быть проблемы с обычными операциями AutoCAD, когда не нужно производить действие сразу с обоими примитивами (например, _MOVE)
2) один или оба объекта скопировали в пределах чертежа - какие теперь должны быть метки у новых объектов и как их присвоить?
Андрей. Что делать с моим пунктом 2) и как это обрабатывается указанным кодом?Скопированный объект содержит те же элементы в TopHandles. Список BottomHandles очищается, поскольку на новый объект ещё никто не завязывался.
Конечно же, придется написать еще с десяток-другой дополнительных методов и молиться, что все предусмотрели...А еще учесть особенности поведения различных версий AutoCAD, значений системных переменных и т.д... Могу посочувствовать если это придется реализовывать.
что бы связать два примитива междуха-ха три раза.
собой на столько надежно, то бы эта связь оставалась стабильной при любых
необдуманных и обдуманных действиях пользователей
хотим чтобы работало стабильно и без сбоевВ ту же корзину.
Думаю вот, что может у инициатора данной темы попросить четкиеМеня интересовали не пути решения этой задачи, а есть ли стандартный инструмент в API для этого.
требования к этой задачи и тогда из этих требований уже выработать
конепт проекта. После чего приступить к решению задачи.
Хотя бы выяснить систему связей какие они
- двунаправленные
- однонаправленные
- разветвленные
или все варианта может еще какие варианты
Потому как на конкретном примере думается легче.
Я вот к примеру решал подобную задачу 2005 году в MicroStation V8
связей объектов для строительства наружных сетей.
Может будут еще варианты, которые я упустил?Дмитрий, может вариант сломать систему блок - мультивыноска подойдет? А вариант в Civil: COGO с РД - метка?
К тому же, идея такая, что пользователи будут сами создавать блоки для своих деталей, без моего участия...Я как раз-расписывал "спецуху" как создавать такие аттрибуты (и не только их, там мануал на создание блоков на 3 страницы был).
лучше, чтобы проектировщик имел свободу для творчества в этом плане.ИХМО наоборот "красивей" получается, когда все стрелочки в одинаковое место указывают.
Да, придется попотеть- как сделаешь - напиши мне тоже интересно...
Из минусов - если редактировать чертеж неаккуратно, то выноски могут указывать на пустое местоПроверка на пустое место выполняется легко: на основе хэндла пытаешься получить ObjectId (метод называется TryGetObjectId, если мне не изменяет память). если для указанного хэндла не существует соответствующего ObjectId, то это оно и есть - "пустое место".
или вообще на другой объект чертежа, т.к. они никак не связаны с блоком, на который должны указывать.Чтобы это проверить, в том объекте, на который хранишь ссылку, создай РД в которых запиши, к примеру, GUID. А в РД своей ссылки, помимо ID связанного объекта, дополнительно храни так же значение этого GUID.
- Хендл объекта выноски.Юзер копирует вхождение блока из одного чертежа в другой, посредством Ctrl + C \ Ctrl + V и весь твой план сразу идёт лесом, ибо обозначенной тобой информации становится явно недостаточно.
- Хендл объекта таблицы спецификации.
- № выноски (для восстановления удаленного объекта выноски).
Вот и я об этом - хочется сделать так, чтобы пользователям потом было легче. Пусть для этого мне придется сейчас больше поработать. Думаю, все должно получиться. Если осилю - поделюсь :)К тому же, идея такая, что пользователи будут сами создавать блоки для своих деталей, без моего участия...Я как раз-расписывал "спецуху" как создавать такие аттрибуты (и не только их, там мануал на создание блоков на 3 страницы был).лучше, чтобы проектировщик имел свободу для творчества в этом плане.ИХМО наоборот "красивей" получается, когда все стрелочки в одинаковое место указывают.Да, придется попотеть- как сделаешь - напиши мне тоже интересно...
Я имел в виду геометрическое указание, как на картинке. После сдвига деталей, одна выноска указывает не на ту деталь, вторая - в пустое место. И в том варианте, в котором я озвучивал этот минус, никак не "отловить" такие невзаимные изменения.ЦитироватьЦитата: Загорулькин Дмитрий от 03-07-2014, 14:18:35Проверка на пустое место выполняется легко: на основе хэндла пытаешься получить ObjectId (метод называется TryGetObjectId, если мне не изменяет память). если для указанного хэндла не существует соответствующего ObjectId, то это оно и есть - "пустое место".
Из минусов - если редактировать чертеж неаккуратно, то выноски могут указывать на пустое местоЦитироватьЦитата: Загорулькин Дмитрий от 03-07-2014, 14:18:35Чтобы это проверить, в том объекте, на который хранишь ссылку, создай РД в которых запиши, к примеру, GUID. А в РД своей ссылки, помимо ID связанного объекта, дополнительно храни так же значение этого GUID.
или вообще на другой объект чертежа, т.к. они никак не связаны с блоком, на который должны указывать.
Т.о. сначала ищешь объект, ID которого соответствует значению хэндла, хранящегося в РД. Если объект не найден, значит ссылка битая (выполняешь соответствующие исправления). Если найден объект с указанным хэндлом, то на следующем этапе выполняешь проверку соответствия GUID. Ежели проверка прошла, значит объект, скорее всего корректен.
Я бы решал так:
1) Создал библиотеку блоков (графических образов объектов) и в РД вставок блоков записывал следующее:
- Хендл объекта выноски.
- Хендл объекта таблицы спецификации.
- № выноски (для восстановления удаленного объекта выноски).
2) Сделал алгоритм обновления (генерации) содержимого в табличке спецификации на основе имеющихся вставок блоков на чертеже. В таблицу заносились бы только данные по утвержденному списку имен блоков. Справочник имен блоков хранил бы в соотв. dwg или dwt файле.
3) Анализ возможных действий пользователя:
a) удаление объекта вставки блока – алгоритм обновления удаляет выноску и обновляет содержимое таблицы.
b) удаление объекта выноски - алгоритм обновления снова возобновит объект выноски.
c) удаление таблицы спецификации - алгоритм обновления создает таблицу снова и заполняет ее в соотв. с
имеющимися объектами на чертеже.
d) копирование или создание вставки блока - алгоритм обновления создает выноску (если нужна),
связывает ее с блоком и снова обновляет таблицу и заносит нужные данные в РД вставки блока.
e) пользователь создает копию таблицы спецификации – алгоритм обновления ни как ни реагирует на эту
таблицу, т.к. каждый объект вставки блока не хранит в РД Хендл в этой копии таблицы.
f) копирование или создание выноски – если алгоритм обновления не найдет вставку блока в РД, которого
есть Хандл этой выноски, то он проигнорирует ее. А если найдет, то связь есть, только вот геометрическое
положение выноски может быть не таким, каким нужно.
g) копирование примитивов в другой чертеж - алгоритм обновления скорее не найдет связи таблицы
и вставок блоков и сформирует новую таблицу. Выноски лучше вообще удалить и сформировать новые,
взяв из РД блоков их номера.
Общий смысл работы в том, что есть алгоритм обновления который в текущей ситуации принимает решение и восстанавливает таблицу спецификации или обновляет ее.
Я имел в виду геометрическое указание, как на картинке. После сдвига деталей, одна выноска указывает не на ту деталь, вторая - в пустое место. И в том варианте, в котором я озвучивал этот минус, никак не "отловить" такие невзаимные изменения.Тогда, как вариант к размышлению:
Юзер копирует вхождение блока из одного чертежа в другой, посредством Ctrl + C \ Ctrl + V и весь твой план сразу идёт лесом, ибо обозначенной тобой информации становится явно недостаточно.
- Может быть, есть какое-то еще событие базы данных/документа/приложения/системы, чтобы можно было отловить копирование объектов через буфер обмена?
Действительно, все получилось сделать:- создать связи- сохранить связи в чертеже- восстановить и актуализировать информацию при открытии чертежа- отловить событие копирования связанных объектов внутри чертежа и добавить связь копиям- отловить событие модификации связанных объектов и сгенерировать события для того, чтобы приложение, пользующееся функционалом связей, могло каким-то образом на это отреагироватьА ежели Database отредактируют на машине, на которой нет твоего плагина?
Но вот через буфер обмена никак не получается пробиться. Загвоздка в том, что такое копирование как-то хитро работает.В составе IdMapping хранится информация о том, какому идентификатору нового объекта соответствует какой идентификатор копируемого из др. чертежа объекта. Имея на руках эту инфу, ты можешь и расширенные данные подтянуть соответствующим образом и не важно сколько там промежуточных временных файлов создаётся за кулисами (если я верно понял твой вопрос).
Если нужно обратиться к добавляемому в документ примитиву,С этим проблем нет, какие примитивы добавляются в базу я вижу через IdMapping.
то можно обработать событие добавления примитива в документ.
В составе IdMapping хранится информация о том, какому идентификатору нового объекта соответствует какой идентификатор копируемого из др. чертежа объекта. Имея на руках эту инфу, ты можешь и расширенные данные подтянуть соответствующим образом и не важно сколько там промежуточных временных файлов создаётся за кулисами (если я верно понял твой вопрос).Думаешь, в промежуточных Database ID и/или хендлы объектов не меняются? Мысль интересная, спасибо! Надо проверить. Завтра первым делом займусь этим :) Кстати, расширенные данные я не использую совсем. За основу взял твою идею "менеджера связей", между сеансами сохраняю его в NOD базы чертежа.
Если "нормально" совсем никак, то вариант - попробывать использовать грубый вариант - Document.CommandWillStart - смотреть соответствующие команды работы с буфером обмена и варианты завершения Command(...) c дальнейшим анализом Clipboard.GetData(...).Тоже дельная мысль, спасибо!
Если "нормально" совсем никак, то вариант - попробывать использовать грубый вариант - Document.CommandWillStartКстати, именно этот вариант я несколько лет назад использовал, когда нужно было отслеживать копирование пользователем таблиц из Excel и вставку их в AutoCAD: отлавливал запуск команды вставки из буфера (сейчас точного имени не помню, но ты и сам можешь легко это выяснить) и анализировал содержимое буфера обмена. Если там находился OLE объект от Excel'я, то выполнял преобразование контента в соответствующим образом отформатированную таблицу AutoCAD, которую затем вставлял в указанное юзером место (висела на курсоре, ожидая вставки). Так что способ отслеживания Ctrl + V посредством мониторинга Document.CommandWillStart работает на 100%.
- Все ли правильно с событием WblockNotice? Может быть, в аргументах там должна фигурировать еще и вторая база данных?Всё правильно, но ты сравниваешь не те базы. Нужно сравнивать e.To и HostApplicationServices.WorkingDatabase
Думаешь, в промежуточных Database ID и/или хендлы объектов не меняются?Меняются конечно, но через IdMapping ты как раз можешь отследить что было и что стало. И более то ты можешь в нужный момент в IdMapping подсунуть NOD, чтобы и она скопировалась, если в этом есть необходимость.
[Doc Event] : Command will Start : COPYBASE
Базовая точка:
[Editor Event] : Prompting For Point
[Editor Event] : Point Filter
[Editor Event] : Point Monitor
[Editor Event] : Prompting For Selection
[Editor Event] : Selection Added
[Editor Event] : Prompt For Selection Ending
[Editor Event] : Prompted For Selection
[Editor Event] : Point Filter
[Editor Event] : Point Monitor
[Editor Event] : Point Filter
[Editor Event] : Point Monitor
[Editor Event] : Point Filter
[Editor Event] : Point Monitor
[Editor Event] : Prompted For Point
[Editor Event] : Prompting For Selection
[Editor Event] : Selection Added найдено: 5
[Editor Event] : Prompting For Selection
[Editor Event] : Prompt For Selection Ending
[Editor Event] : Prompted For Selection
[Editor Event] : Prompting For Selection
[Editor Event] : Prompt For Selection Ending
[Editor Event] : Prompted For Selection
[Editor Event] : Prompting For Selection
[Editor Event] : Prompt For Selection Ending
[Editor Event] : Prompted For Selection
[Editor Event] : Prompting For Selection
[Editor Event] : Prompt For Selection Ending
[Editor Event] : Prompted For Selection
[Doc Event] : Implied Selection Changed
[Editor Event] : Prompt For Selection Ending
[Editor Event] : Prompted For Selection
[DB Event : 749142272] : Object Modified : <DrawOrderTable, 27F0>
[DB Event : 749142272] : Object Modified : <DrawOrderTable, 27F0>
[DB Event : 749142272] : Object Modified : <BlockTableRecord, 1F>
[DB Event : 749142272] : Object Modified : <BlockTableRecord, 5D>
[DB Event : 749142272] : Object Modified : <BlockTableRecord, 1F>
[DB Event : 749142272] : Object Modified : <BlockTableRecord, 119C>
[DB Event : 749142272] : Object Modified : <BlockTableRecord, 11A4>
[DB Event : 749142272] : Object Modified : <BlockTableRecord, 9B16>
[DB Event : 749142272] : Object Modified : <BlockTableRecord, 9B3B>
[DB Event : 749142272] : Object Modified : <BlockTableRecord, 9B60>
[DB Event : 749142272] : Object Modified : <BlockTableRecord, 9B86>
[DB Event : 749142272] : Object Modified : <BlockTableRecord, 9BAC>
[DB Event : 749142272] : Object Modified : <BlockTableRecord, 9BD3>
[DB Event : 749142272] : Object Modified : <BlockTableRecord, AF81>
[DB Event : 749142272] : Object Modified : <BlockTableRecord, 11759>
[DB Event : 749142272] : Object Modified : <BlockTableRecord, 11778>
[DB Event : 749142272] : Object Modified : <BlockTableRecord, 117AF>
[DB Event : 749142272] : Object Modified : <BlockTableRecord, 11B71>
[DB Event : 749142272] : Object Modified : <BlockTableRecord, 13A73>
[DB Event : 749142272] : Object Modified : <BlockTableRecord, 13A8C>
[DB Event : 749142272] : Object Modified : <BlockTableRecord, 13ABC>
[DB Event : 749142272] : Object Modified : <BlockTableRecord, 13AD9>
[DB Event : 749142272] : Object Modified : <BlockTableRecord, 13B08>
[DB Event : 749142272] : Object Modified : <BlockTableRecord, 13B50>
[DB Event : 749142272] : Object Modified : <BlockTableRecord, 13B6B>
[DB Event : 749142272] : Object Modified : <BlockTableRecord, 13B92>
[DB Event : 749142272] : Object Modified : <BlockTableRecord, 13BAD>
[DB Event : 749142272] : Object Modified : <BlockTableRecord, 13BC8>
[DB Event : 749142272] : Object Modified : <BlockTableRecord, 13BE2>
[DB Event : 749142272] : Object Modified : <BlockTableRecord, 13BF8>
[DB Event : 749142272] : Object Modified : <BlockTableRecord, 13C11>
[DB Event : 749142272] : Object Modified : <BlockTableRecord, 13C62>
[DB Event : 749142272] : Object Modified : <BlockTableRecord, 13C7E>
[DB Event : 749142272] : Object Modified : <BlockTableRecord, 14584>
[DB Event : 749142272] : Object Modified : <BlockTableRecord, 146A7>
[DB Event : 749142272] : Object Modified : <BlockTableRecord, 146AC>
[DB Event : 749142272] : Object Modified : <BlockTableRecord, 146B1>
[DB Event : 749142272] : Object Modified : <BlockTableRecord, 146B7>
[DB Event : 749142272] : Object Modified : <BlockTableRecord, 148AC>
[DB Event : 749142272] : Object Modified : <BlockTableRecord, 155AD>
[DB Event : 749142272] : Object Modified : <BlockTableRecord, 15E59>
[DB Event : 749142272] : Object Modified : <BlockTableRecord, 17792>
[DB Event : 749142272] : Object Modified : <BlockTableRecord, 1F05A>
[DB Event : 749142272] : Object Modified : <BlockTableRecord, 1F085>
[DB Event : 749142272] : Object Modified : <BlockTableRecord, 1F4B7>
[DB Event : 749142272] : Object Modified : <BlockTableRecord, 1F8E2>
[DB Event : 749142272] : Wblock Notice : To = C:\Users\Zagorulkin_DY\appdata\local\autodesk\c3d 2014\rus\template\_autocad civil 3d (metric)_rus.dwt
[DB Event : 55343840] : Database Constructed
[Editor Event] : Selection Added
[Editor Event] : Prompting For Selection
[Editor Event] : Selection Added
[Editor Event] : Prompt For Selection Ending
[Editor Event] : Prompted For Selection
[Editor Event] : Prompting For Selection
[Editor Event] : Selection Added
[Editor Event] : Prompt For Selection Ending
[Editor Event] : Prompted For Selection
[Editor Event] : Prompting For Selection
[Editor Event] : Selection Added
[Editor Event] : Prompt For Selection Ending
[Editor Event] : Prompted For Selection
[Editor Event] : Prompting For Selection
[Editor Event] : Selection Added
[Editor Event] : Prompt For Selection Ending
[Editor Event] : Prompted For Selection
[Doc Event] : Implied Selection Changed
[Doc Event] : Command Ended : COPYBASE
Ключевой для меня момент - [DB Event : 55343840] : Database Constructed, т.е., создание базы данных отловить можно! Просто для этого нужно использовать события не отдельного объекта Database, а класса Database![EVENT REACTOR] : [Wblock Notice] (Db = 000000002A4443E0 "C:\Temp\Drawing1_1_1_1438.sv$")
[EVENT REACTOR] : [Begin Deep Clone: context = Wblock] (Db = 0000000030E60EF0 "")
Соотвественно текущая база и та, в которую выполняется Wblock - разные.
а некоторые еще и неправильно работают.Autodesk не даёт расслабляться...
Я вижу, что ты воспользовался не ARXDBG, а MGDDBG. И похоже я прав, что далеко не все реакторы ObjectARX имеют эквиваленты в AutoCAD .NET API, а некоторые еще и неправильно работают. В частности WblockNotice. В ObjectARX в такой же ситуации:Да, у меня MGDDBG уже была на компьютере, решил ей воспользоваться. Думал, что большой разницы между ними нет...Код: [Выделить][EVENT REACTOR] : [Wblock Notice] (Db = 000000002A4443E0 "C:\Temp\Drawing1_1_1_1438.sv$")
Соотвественно текущая база и так, в которую выполняется Wblock - разные.
[EVENT REACTOR] : [Begin Deep Clone: context = Wblock] (Db = 0000000030E60EF0 "")
Db = 0000000030E60EF0
а некоторые еще и неправильно работают...А почему это ошибка (я просто спрашиваю, а не говорю что все правильно), или если так правильней в чем именно ошибка - копипаста-то работает (а как им там внутри это реализовывать это ихмо их дело).
Соотвественно текущая база и так, в которую выполняется Wblock - разные.
А что это за идентификатор базы?Я посмотрел в коде ARXDBG - это просто адрес в памяти, где расположен это объект.
А почему это ошибка (я просто спрашиваю, а не говорю что все правильно), или если так правильней в чем именно ошибка - копипаста-то работает (а как им там внутри это реализовывать это ихмо их дело).Дима. В ObjectARX есть два реактора:
[EVENT REACTOR] : [Wblock Notice] (Db = 000000002A4443E0 "C:\Temp\Drawing1_1_1_1438.sv$")
[ED REACTOR] : [Wblock Notice] (Db = 000000002A4443E0 "C:\Temp\Drawing1_1_1_1438.sv$")
Database.WblockNotice должно быть "оберткой" для AcRxEventReactor::wblockNotice (исходя тоже из документации) и соотвественно должна возвращать базу в которую будет выполняться Wblone. Но похоже это не так.Я посмотрел в коде ARXDBG - это просто адрес в памяти, где расположен это объект.Эх, жаль. Я думал, что это какой-то уникальный идентификатор базы данных. Пока я такого не смог найти. Может быть, Вы подскажете? :)
Но похоже это не так.Можете сами проверить. Возможно и АДН это интересно будет :)
Я посмотрел в коде ARXDBG - это просто адрес в памяти, где расположен это объект.
Эх, жаль. Я думал, что это какой-то уникальный идентификатор базы данных.Ну, с некоторыми ограничениями, это в общем-то так.
По какому свойству я могу определить, что они разные?Оххх... По поводу сравнения объектов это тема реально на целую книгу. Что есть "одинаковые БД", equal как-раз таки и проверяет ссылаются ли объекты на один и тот-же физический адрес (то есть, что это одно и то-же). А вот если дважды открыть один и тот-же файл можно-ли это рассматривать как "одиноковые" БД - вопрос не однозначен (по крайней мере время открытия будет разным, handle внутренних объектов то-же и пр.), то есть надо определиться, что все-таки важно в сравнении - быть может, например, достаточно будет сверить свойства Filename...
А из NET к нему можно добраться?Да. Database.UnmanagedObject
У меня в одной переменной сохранена одна БД, в другой - другая.Только по полному пути доступу к файлу, если они сохранены. А если они не сохранены, то непонятны критерии сравнения на эквивалентность.
Команда: _pasteclip Повторное определение блока _Oblique пропущено.
DeepCloneContext: Insert
OriginalDatabase: 1221104048 FileName: C:\Users\ZAGORU~1\AppData\Local\Temp\A$C7CEB7907.DWG
DestinationDatabase: 766323488 FileName: C:\Users\Zagorulkin_DY\appdata\local\autodesk\c3d 2014\rus\template\_autocad civil 3d (metric)_rus.dwt
IdPairs:
ObjectType: AcDbLine, KeyId: (8796086484512), ValueId: (8796086071728), KeyHandle: 2019B, ValueHandle: 2019B <------------------------------- !!! Хендлы одинаковые
ObjectType: AcDbCircle, KeyId: (8796086484528), ValueId: (8796086071744), KeyHandle: 2019C, ValueHandle: 2019C <------------------------------- !!! Хендлы одинаковые
DeepCloneContext: Insert
OriginalDatabase: 1221104048 FileName: C:\Users\ZAGORU~1\AppData\Local\Temp\A$C7CEB7907.DWG
DestinationDatabase: 766323488 FileName: C:\Users\Zagorulkin_DY\appdata\local\autodesk\c3d 2014\rus\template\_autocad civil 3d (metric)_rus.dwt
IdPairs:
ObjectType: AcDbLine, KeyId: (8796086484512), ValueId: (8796086071728), KeyHandle: 2019B, ValueHandle: 2019B <------------------------------- !!! Хендлы одинаковые
ObjectType: AcDbCircle, KeyId: (8796086484528), ValueId: (8796086071744), KeyHandle: 2019C, ValueHandle: 2019C <------------------------------- !!! Хендлы одинаковые
Точка вставки:
DeepCloneContext: Explode
OriginalDatabase: 766323488 FileName: C:\Users\Zagorulkin_DY\appdata\local\autodesk\c3d 2014\rus\template\_autocad civil 3d (metric)_rus.dwt
DestinationDatabase: 766323488 FileName: C:\Users\Zagorulkin_DY\appdata\local\autodesk\c3d 2014\rus\template\_autocad civil 3d (metric)_rus.dwt
IdPairs:
ObjectType: AcDbLine, KeyId: (8796086071728), ValueId: (8796086071840), KeyHandle: 2019B, ValueHandle: 201A2
ObjectType: AcDbCircle, KeyId: (8796086071744), ValueId: (8796086071856), KeyHandle: 2019C, ValueHandle: 201A3
Разобрался с копированием объектов из чертежа во временный чертеж в папке Temp.В этом процессе все логично и понятно.
IdMapping показывает уже совершенно другие хендлы!Вся беда в том, что примитивы при вставке берутся не из файла в папке temp - проверить просто - сотри их - вставка продолжит работать - хотя может как кэш он и используется - надо "рыть" - смотреть, что еще есть в Clipboard.GetDataObject().GetFormats() и где-то там, что-то явно лежит, на основе чего база и создается (и дай бог чтоб, это был какой-нибудь поток в памяти с "честным" файлом, а если это не так - то может и придется координально менять тактику).
Возможно и так, но это не объясняет, почему в разных базах данных объекты имеют одинаковые хендлы.А что в этом не так? Могут иметь - не вижу в этом противоречия.
P.S. Александр Наумович, очень прошу Вас (если, конечно, возможности/время позволяет) проверить, что выдаст при вставке ARXовский аналог IdMapping! Я, конечно, могу оказаться неправ, но пока я склоняюсь к тому, что проблема именно из-за неправильной реализации.Боюсь что проблема вот в следующем. В момент возникновения события BeginDeepCloneTranslation IdMapping еще неправильный (необработанный) о чем говорится в документации. Правильным IdMapping становится в момент события AcEditorReactor::endDeepClone, эквивалент которого в .NET API Database.DeepCloneEnded. Но тут то и возникает проблема, т.к. у Database.DeepCloneEnded нет параметра, в котором был бы IdMapping, а у AcEditorReactor::endDeepClone он есть. Так что как получить правильный IdMapping в AutoCAD .NET API я сейчас даже и не соображу...
А хендлы я уже из Id получаю, может тут какой подвох?Подвох в том, что в тот момент когда ты их получаешь они еще не вычислены, т.е. не содержат правильные значения.
Подвох в том, что в тот момент когда ты их получаешь они еще не вычислены,Кто не вычесленны id или handle - если handle - тогда все просто - сохранить IdMapping на момент вызова BeginDeepCloneTranslation, а получить handle по событию DeepCloneEnded - но ИХМО тут загвоздка еще в чем-то (то есть такой вариант скорее всего вернет все тоже-самое). Я думаю, что где-то в этой цеопчке создаются все-же невидимая для событий база - ту в которую копируют и соответственно "цепочка" преобразований - с пропуском.
Кто не вычесленны id или handle - если handle - тогда все просто - сохранить на момент вызова BeginDeepCloneTranslation, а получить handle по событию DeepCloneEndedДумаю что именно так и нужно сделать.
Попробовал сохранить объект IdMapping в событии BeginDeepClone и прочитать его в событии EndDeepClone - объект IdMapping между этими событиями не изменился (хотя, особой надежды не было)Объект IdMapping сохранять смысла я не вижу. Наверное нужно сохранять Id'сы для всех пар, а в EndDeepClone получать для них Handle'ы
Наверное нужно сохранять Id'сы для всех парВот тут я точно не вижу смысла. Могут измениться объекты - но id сами по себе точно не "испортяться" - другое дело, что они могут потерять актуальность (то есть на момент завершения они уже станут другими - но это нам все равно никак не поможет).
А когда у нас идет наполнение БД из файла без его открытия (например, методом ReadDwgFile) хендлы объектов чертежа сохраняются?Конечно.
И? Не знаю как Дима_, а я уже совсем запутался.Да я тоже (с учетом что паралельно как-бы работаю - но телефон свирепо насвистывает входящие emailики) - мысль про ид сейчас проверю сам и если цепочка будет покажу лог.
Команда: _circle Центр круга или [3Т/2Т/ККР (кас кас радиус)]: *Прервано*
Команда: netload
Команда: test
Команда: _circle Центр круга или [3Т/2Т/ККР (кас кас радиус)]:
Радиус круга или [Диаметр]:
Команда: (cdr (assoc 5 (entget (entlast))))
"1FB"
Команда: _copyclip найдено: 1
From C:\Users\Дима\AppData\Local\Autodesk\AutoCAD
2010\R18.0\rus\template\acadiso.dwt
To
1FB(2129671192)->4F(2129686136);
Команда: _pasteclip
From C:\Users\1F43~1\AppData\Local\Temp\A$C53B37EF2.DWG
To C:\Users\Дима\AppData\Local\Autodesk\AutoCAD
2010\R18.0\rus\template\acadiso.dwt
1FD(2129686136)->1FD(2129671208); Точка вставки:
From C:\Users\Дима\AppData\Local\Autodesk\AutoCAD
2010\R18.0\rus\template\acadiso.dwt
To C:\Users\Дима\AppData\Local\Autodesk\AutoCAD
2010\R18.0\rus\template\acadiso.dwt
1FD(2129671208)->202(2129671248);
Команда: (cdr (assoc 5 (entget (entlast))))
"202"
Команда: _pasteclip
From C:\Users\1F43~1\AppData\Local\Temp\A$C53B37EF2.DWG
To C:\Users\Дима\AppData\Local\Autodesk\AutoCAD
2010\R18.0\rus\template\acadiso.dwt
204(2129706616)->204(2129671264); Точка вставки:
From C:\Users\Дима\AppData\Local\Autodesk\AutoCAD
2010\R18.0\rus\template\acadiso.dwt
To C:\Users\Дима\AppData\Local\Autodesk\AutoCAD
2010\R18.0\rus\template\acadiso.dwt
204(2129671264)->209(2129671304);
Команда: (cdr (assoc 5 (entget (entlast))))
"209"
то есть имея исходный handle 1Fb - через Id он легко прослеживается до конечного 202Если объекты копировать в чертеже любыми командами: копирование, зеркало и т.п., то связи к новым объектам тоже добавляются.На этой фразе я понял, что где-то я такое уже видел - а ведь по сути то же самое реализованно в самом автокаде (интересно можно-ли воспользоваться для любых объектов, а не только для текстов и выносок), ведь если создать поле на объект, то при копировании его с целевым объектом (так-же неважно куда и как) ссылка "перерегестрируется" (будет видно при регенарции) - причем для этого ничего запущенного в памяти не нужно (то есть пара всегда будет связанна - вне зависимости на какой машине с ней работали, как копировали и пр.)
Код написанн красиво и главное разборчиво...Спасибо! IntelliSence помогал :)
интересно можно-ли воспользоваться для любых объектов, а не только для текстов и выносокБыло бы неплохо, но вряд ли такое возможно.
Если подскажете, как можно отловить изменение объекта через панель свойств без использования Database.ObjectModified - буду очень признателен!Подпишись на событие DocumentLockModeWillChange
Например, в Editor.EnteringQuiescentState?В жизни не догадался бы... Я так понимаю, это какая-то реакция на "безмолвные" редактирования?
Я так понимаю, это какая-то реакция на "безмолвные" редактирования?Точнее реакция на то, что ничего в AutoCAD не происходит и он ожидает действия пользователя.
Меняет, правда, не сразу, а только при переходе в чертеж из палитры свойств.Ну в этом событии именно так и должно быть.
<DOC REACTOR: Чертеж1.dwg> : [Document Lock Mode Will Change]
MyCurMode: Not Locked
MyNewMode: Write | Protected Auto Write
CurMode: Not Locked
CmdName: PARTIALREGEN
<DOC REACTOR: Чертеж1.dwg> : [Document Lock Mode Will Change]
MyCurMode: Auto Write
MyNewMode: Not Locked
CurMode: Auto Write
CmdName: #
<DOC REACTOR: Чертеж1.dwg> : [Document Lock Mode Changed]
MyPrevMode: Auto Write
MyCurMode: Not Locked
CurMode: Not Locked
CmdName: #
<DOC REACTOR: Чертеж1.dwg> : [Document Lock Mode Changed]
MyPrevMode: Not Locked
MyCurMode: Write | Protected Auto Write
CurMode: Write | Protected Auto Write
CmdName: PARTIALREGEN
<DOC REACTOR: Чертеж1.dwg> : [Document Lock Mode Will Change]
MyCurMode: Write | Protected Auto Write
MyNewMode: Not Locked
CurMode: Write | Protected Auto Write
CmdName: #PARTIALREGEN
<DOC REACTOR: Чертеж1.dwg> : [Document Lock Mode Changed]
MyPrevMode: Write | Protected Auto Write
MyCurMode: Not Locked
CurMode: Not Locked
CmdName: #PARTIALREGEN
Попробовав разные варианты (и словив кучу ошибок :)), пришел к выводу, что надо попадать в предпоследнее событие с помощью проверки:Все остальное берут на себя внутренние механизмы AutoCAD! Никаких обработчиков событий, актуализаторов и прочей головной боли! :-\К сожалению это работает не во всех сценариях даже для Custom Object/Entity.
Подскажете, что надо сделать, чтобы вызвать сбой?Возможно в твоём сценарии использования связи между объектами чертежа на такой сбой никогда не попадёшь. У меня были проблемы с редактированием ручек Custom Entity, когда необходимо было обработать связанные примитивы.
Во внутреннем механизме AutoCAD это реализовано немного иначе. Если объекты копируются парами - то так же как у меня, а вот если один объект из пары - то у копии появляется связь к связанному объекту оригинала.Фактически об этом я и говорил. И это в моём случае было недопустимо. Т.е. если выбран один из объектов для копирования, то необходимо было добавить в набор все связанные объекты для копирования. И в копиях ссылки должны были быть на копии, а не на оригиналы.
Желательно сразу включить запись лога в файл, так как будет очень много сообщенийИзвините, не относится к теме обсуждения.
Александр, подскажите пожалуйста как включить запись лога в файл в ARXDBG.Так это же стандартный AutoCAD'овский log-файл. Т.е. включается/выключается командами _LOGFILEON/_LOGFILEOFF
Спасибо, Александр. Не знал об этой командеЕсть еще системная переменная LOGFILEPATH для задания пути к log-файлу: http://help.autodesk.com/view/ACD/2017/RUS/?guid=GUID-0E2D4DF2-4C26-48AC-ACBC-819E3C46CE59