Посоветуйте способ отслеживания изменений в листах

Автор Тема: Посоветуйте способ отслеживания изменений в листах  (Прочитано 17592 раз)

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

Оффлайн JohnJАвтор темы

  • ADN Club
  • **
  • Сообщений: 78
  • Карма: 1
  • c# autocad
  • Skype: johnj255work
Задача такова: в модели что-то изменили: добавили, удалили, либо изменили маленькую часть длинной полилинии, превратили объект в блок или, наоборот, блок разбили.
Нужно найти листы, в видовых экранах которых отображаются места модели, где произошли изменения. Каким способом лучше всего воспользоваться?
Я пока придумал два способа:
1. Проверять по координатам объекты, отображающиеся в видовом экране и сравнивать с оригиналом. Данным способом, я считаю, очень сложно всё учесть, особенно в случае непрямоугольных видовых экранов.
2. Экспортировать лист в модель отдельного чертежа и уже потом воспользоваться п.1. Тоже сложно, но чуть-чуть проще.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Данным способом, я считаю, очень сложно всё учесть, особенно в случае непрямоугольных видовых экранов.
А другого способа и нет. Только проверять не координаты, а BoundingBox. Экспортировать лист в модель - это не метод.
Вообще мне интересно как ты планировал всё это реализовать? В обработчике событий Database.ObjectXXXX ? Представляю себе какие "тормоза" бы были у AutoCAD.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн JohnJАвтор темы

  • ADN Club
  • **
  • Сообщений: 78
  • Карма: 1
  • c# autocad
  • Skype: johnj255work
Просто если изменяется лишь малая часть объекта, частично отображаемого в видовом экране листа, притом изменяется та часть, которую в листе не видно. С точки зрения кода, объект изменён. С точки зрения задачи - содержимое, отображаемое на листе не поменялось. Как это учесть без эспортирования в модель? А вот экспорт в модель, по идее, обрежет лишние части и в обоих случаях (в оригинале и в изменённом файле) эти листы будут определяться одинаковыми, разве нет?

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
А вот экспорт в модель, по идее, обрежет лишние части и в обоих случаях (в оригинале и в изменённом файле) эти листы будут определяться одинаковыми, разве нет?
А вот это проверь сам. Тем не менее я считаю, что это не вариант. Даже если это и так, то ты получишь в модели новый вариант листа. И что дальше? Как ты его будешь сравнивать с исходным? И что это тебе в результате даст?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн JohnJАвтор темы

  • ADN Club
  • **
  • Сообщений: 78
  • Карма: 1
  • c# autocad
  • Skype: johnj255work
Ну есть два файла: текущий и оригинал. Проверяя изменения, я экспортирую лист из текущего документа в модель (создавая новый файл), затем экспортирую этот лист из оригинала в модель (создавая ещё один новый файл), и потом уже их сравниваю. По крайней мере, идея на данный момент такова.  А обрезка объектов выполняется - проверил. Даже блок каким-то образом обрезал по краю видового экрана. Я пока не разбирался, как именно, но в редакторе блок выглядит целым.
Цитировать
Вообще мне интересно как ты планировал всё это реализовать? В обработчике событий Database.ObjectXXXX ? Представляю себе какие "тормоза" бы были у AutoCAD.
В крайнем случае, можно отдельной командой: НАЙТИИЗМЕНИВШИЕСЯЛИСТЫ. И пусть весь мир подождёт :)

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

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Тут еще в зависимости от задачи можно рассмотреть вариант сравнивать растр.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Даже блок каким-то образом обрезал по краю видового экрана. Я пока не разбирался, как именно, но в редакторе блок выглядит целым.
Подозреваю, что он его не резал, а просто сделал ему подрезку (XCLIP) - это значит, что для тебя это фактически оригинальный блок без никакой подрезки.
В крайнем случае, можно отдельной командой: НАЙТИИЗМЕНИВШИЕСЯЛИСТЫ. И пусть весь мир подождёт :)
Перед тем как приступать к реализации сначала задумайся над следующими вопросами:
1) Окружности одинакового радиуса, цвета, слоя, но с разным уровнем (Elavation) - это одинаковая окружности или нет?
2) Абсолютно одинаковые окружности, но одна в блоке, а друга нет - это одинаковые окружности или нет?
3) Окружность и эллипс с одинаковыми осями - это одно и тоже?
4) Главный вопрос: "Каковы критерии "одинаковости" чертежей?"
Ну и еще осталось решить в каком виде ты дашь пользователю полюбоваться на результаты сравнения.

P.S.: Думаешь почему за 30 (с гаком) лет существования AutoCAD нет нормальной команды для сравнения чертежей?
Тут еще в зависимости от задачи можно рассмотреть вариант сравнивать растр.
;D  ;D  ;D
А как ты рассчитываешь эти растры получить? Переключаться на каждый из листов и печатать их в растровые форматы???
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Часть обсуждения, связанную с организацией проектирования, перенес сюда: http://adn-cis.org/forum/index.php?topic=985.0
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн JohnJАвтор темы

  • ADN Club
  • **
  • Сообщений: 78
  • Карма: 1
  • c# autocad
  • Skype: johnj255work
Подозреваю, что он его не резал, а просто сделал ему подрезку (XCLIP) - это значит, что для тебя это фактически оригинальный блок без никакой подрезки.
К сожалению нет, он именно обрезал и создал новый блок. Причём странный. Он не являлся динамическим, но имя блока начиналось на *. Его описания не существовало. Его не было ни в редакторе блоков, ни где то ещё, кроме модели. Выбрав его, нажимаю "контекстное редактирование блока", говорит "выберите блок". Этот блок не выбирался, хотя при простом выделении, определялся как "Вхождение блока".
Когда я взорвал этот странный блок, то обнаружил вместо кружков, которые были в изначальном блоке и влезли частично, теперь красуются дуги. Когда я взорвал этот странный блок кодом, через block.ExplodeToOwnerSpace(), то так же появились дуги, естественно, но когда я выбрал одну из них в автокаде, то свойства её не отображались и автокад вылетал с критической ошибкой.
Всё это я делал в 2012 автокаде.
В общем, очень интересный блок. Если интересно, могу прислать файлы. А то может я просто что-то не так сделал.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
На полученный чертеж интересно глянуть. Выложи его куда-нибудь и ссылку сюда.
А что по поводу ответов на мои вопросы?

P.S.: Мне это всё напомнило задачу с подсчетом выполненных пользователем команд AutoCAD (их количество, время начала/конца команды, и т.д.). Цель - определить работает ли проектировщик или сачкует. Считаю это бредом.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн JohnJАвтор темы

  • ADN Club
  • **
  • Сообщений: 78
  • Карма: 1
  • c# autocad
  • Skype: johnj255work
Файлик тут: Чертеж_листы_л1.dwg Изначальный файл: Чертеж_листы.dwg
Что касается ваших вопросов: мне хочется сделать именно так, что на все ваши вопросы ответ да. Т.е. любое изменение фиксируется. Но вообще, задача ставилась только о визуальных различиях, поэтому подойдёт и сравнение изображений, как писали выше. В целом по этой теме у меня основные вопросы кончились, я понял суть, как мне кажется. Благодарю всех за участие в обсуждении! Ну, если появятся вопросы - напишу ещё :). Пока остался только вопрос про эти странные блоки. Хорошо было бы научиться с ними работать. Хотя это уже несколько косвенно касается темы.
Слежение за работой проектировщика - идея, конечно, забавная, но нам этого не требуется. Главное, что бы он выполнял работу в срок и качественно, а там пусть как хочет и что хочет делает.
« Последнее редактирование: 03-10-2014, 08:02:03 от JohnJ »

Оффлайн trir

  • ADN Club
  • ****
  • Сообщений: 475
  • Карма: 63
блоки с * - "рабочие" блоки и они часто прячутся от пользователя
сохранил в dxf
правда в АкАд'е он назывался *E33
  0
BLOCK
  5
A4
330
A3
100
AcDbEntity
  8
0
100
AcDbBlockBegin
  2
*E3
 70
     1
 10
0.0
 20
0.0
 30
0.0
  3
*E3
  1

  0
ARC
  5
A0
330
A3
100
AcDbEntity
  8
0
100
AcDbCircle
 10
47.42678073366022
 20
52.02726558122055
 30
0.00000001
 40
47.4267807236602
100
AcDbArc
 50
74.88208761988289
 51
285.1179123801171
  0
ARC
  5
A1
330
A3
100
AcDbEntity
  8
0
100
AcDbCircle
 10
94.85356167000407
 20
99.45404615028724
 30
0.00000001
 40
47.4267807236602
100
AcDbArc
 50
137.6627740968626
 51
222.3372259031374
  0
ARC
  5
A2
330
A3
100
AcDbEntity
  8
0
100
AcDbCircle
 10
91.83878506464258
 20
34.96510435282434
 30
0.00000001
 40
47.4267807236602
100
AcDbArc
 50
132.5028364394449
 51
227.4971635605551
  0
ENDBLK
  5
A5
330
A3
100
AcDbEntity
  8
0
100
AcDbBlockEnd

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
блоки с * - "рабочие" блоки и они часто прячутся от пользователя
Официально они называются анонимными блоками.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Пока остался только вопрос про эти странные блоки. Хорошо было бы научиться с ними работать. Хотя это уже несколько косвенно касается темы.
Это действительно отдельная тема. Работать с ними - это дать возможность пользователю редактировать их? Для этой цели нужно этот блок переименовать. Сделать это стандартными средствами AutoCAD не получится, но написать несложную программку для этого - запросто.
Например, на lisp она будет выглядеть так:

Код - Auto/Visual Lisp [Выбрать]
  1. (defun c:ren_blk ( / a_app a_doc a_blk blk old_name new_name en e)
  2.   (vl-load-com)
  3.   (if (and (setq en (car (entsel "\nВыберите вставку блока: ")))
  4.            (setq e (entget en))
  5.            (= "INSERT" (cdr (assoc 0 e)))
  6.            (setq old_name (cdr (assoc 2 e))))  (progn
  7.     (if (setq new_name (getstring "\nУкажите новое имя блока: ")) (progn
  8.       (cond
  9.         ((tblsearch "BLOCK" new_name)
  10.           (princ "\nБлок с этим именем уже есть!")
  11.         )
  12.         (t
  13.           (setq a_app  (vlax-get-acad-object)
  14.              a_doc  (vla-get-ActiveDocument a_app)
  15.              a_blks (vla-get-Blocks a_doc)
  16.              blk    (vla-Item a_blks old_name)
  17.           )
  18.           (vla-put-name blk new_name)
  19.         )
  20.       )
  21.     ))
  22.   ))
  23. )
« Последнее редактирование: 03-10-2014, 20:05:21 от Александр Ривилис »
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
А так это будет с использованием AutoCAD .NET API:
Код - C# [Выбрать]
  1. using System;
  2. using Autodesk.AutoCAD.Runtime;
  3. using Autodesk.AutoCAD.ApplicationServices;
  4. using Autodesk.AutoCAD.DatabaseServices;
  5. using Autodesk.AutoCAD.Geometry;
  6. using Autodesk.AutoCAD.EditorInput;
  7. using AcRx = Autodesk.AutoCAD.Runtime;
  8. using AcAp = Autodesk.AutoCAD.ApplicationServices;
  9. using AcDb = Autodesk.AutoCAD.DatabaseServices;
  10. using AcGe = Autodesk.AutoCAD.Geometry;
  11. using AcEd = Autodesk.AutoCAD.EditorInput;
  12.  
  13. // This line is not mandatory, but improves loading performances
  14. [assembly: CommandClass(typeof(TestRename.MyCommands))]
  15.  
  16. namespace TestRename
  17. {
  18.   public class MyCommands
  19.   {
  20.     [CommandMethod("RenBlock")]
  21.     public void RenBlock()
  22.     {
  23.       AcAp.Document doc = AcAp.Application.DocumentManager.MdiActiveDocument;
  24.       AcEd.Editor ed = doc.Editor;
  25.       AcEd.PromptEntityOptions pr1 =
  26.         new AcEd.PromptEntityOptions("\nУкажите вставку блока для переименования: ");
  27.       pr1.SetRejectMessage("Это не вставка блока!");
  28.       pr1.AddAllowedClass(typeof(AcDb.BlockReference), true);
  29.       AcEd.PromptEntityResult res1 = ed.GetEntity(pr1);
  30.       if (res1.Status != AcEd.PromptStatus.OK) return;
  31.       AcDb.ObjectId idBtr = AcDb.ObjectId.Null;
  32.       string old_name;
  33.       using (AcDb.BlockReference br =
  34.         res1.ObjectId.Open(AcDb.OpenMode.ForRead) as AcDb.BlockReference)
  35.       {
  36.         idBtr = br.BlockTableRecord;
  37.         using (AcDb.BlockTableRecord btr =
  38.           idBtr.Open(AcDb.OpenMode.ForRead) as AcDb.BlockTableRecord) {
  39.           old_name = btr.Name;
  40.         }
  41.       }
  42.       AcEd.PromptStringOptions pr2 =
  43.         new AcEd.PromptStringOptions("\nУкажите новое имя блока: ");
  44.       pr2.DefaultValue = old_name;
  45.  
  46.       AcEd.PromptResult res2 = ed.GetString(pr2);
  47.       if (res2.Status != AcEd.PromptStatus.OK) return;
  48.      
  49.       string new_name = res2.StringResult;
  50.  
  51.       if (String.Compare(new_name, old_name, true) == 0) return;
  52.       if (AcDb.SymbolUtilityServices.ValidateCompatibleSymbolName(
  53.          new_name, true, false,
  54.          AcDb.SymbolUtilityServices.IsCompatibilityMode(doc.Database)) != AcRx.ErrorStatus.OK)
  55.       {
  56.         ed.WriteMessage("\nНедопустимое имя для блока \'{0}\'!",new_name);
  57.         return;
  58.       }
  59.  
  60.       using (AcDb.BlockTableRecord btr =
  61.         idBtr.Open(AcDb.OpenMode.ForWrite) as AcDb.BlockTableRecord)
  62.       {
  63.         try {
  64.           btr.Name = new_name;
  65.         }
  66.         catch
  67.         {
  68.           ed.WriteMessage("\nБлок \'{0}\' нельзя переименовать в \'{1}\'!",
  69.             old_name, new_name);
  70.         }
  71.       }
  72.     }
  73.   }
  74. }

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