Database.Handseed - очень большое значение.

Автор Тема: Database.Handseed - очень большое значение.  (Прочитано 13843 раз)

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

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Здравствуйте!
Сделал метод для поиска объектов внутри БД чертежа:
Код - C# [Выбрать]
  1. /// <summary>
  2. /// Find a object in the database
  3. /// </summary>
  4. /// <typeparam name="T">Type of the object</typeparam>
  5. /// <param name="db">Database of the drawing</param>
  6. /// <param name="testFunction">Test function for identification of the object</param>
  7. /// <returns>ObjectId or ObjectId.Null if object is not found</returns>
  8. public static ObjectId FindObjectInDatabase<T>
  9.     (this Database db, Func<T, bool> testFunction) where T : DBObject
  10. {
  11.     Handle handseed = db.Handseed;
  12.  
  13.     long handseedTotal = handseed.Value;
  14.  
  15.     for (int i = 1; i < handseedTotal; i++)
  16.     {
  17.         ObjectId currentId = db.IdFromHandleValue(i);
  18.         if (!CheckObjectIdFor<T>(currentId)) continue;
  19.  
  20.         using (T obj = currentId.SafeOpen<T>())
  21.         {
  22.             if (testFunction(obj)) return currentId;
  23.         }
  24.     }
  25.  
  26.     return ObjectId.Null;
  27. }
  28.  
Сделал команду, которая использует этот метод, чтобы найти нужный объект. Запустил. И уже несколько десятков минут жду результат. Остановил, посмотрел промежуточные значения:
handseedTotal = 169059859,
i = 23987369
Посмотрел, какие объекты обрабатываются. Все получаемые currentId - Null. То есть, Handseed имеет большое значение, но до него десятки (сотни?) миллионов номеров не ссылаются на объекты! Получается, что такой метод поиска объектов в базе в таких случаях неоптимален? Или есть какой-то фокус, позволяющий быстро пропускать "пустые" участки номеров?
Вспомогательные методы:
Код - C# [Выбрать]
  1. /// <summary>
  2. /// Восстановление идентификатора объекта из его
  3. /// числового значения хендла
  4. /// </summary>
  5. /// <param name="db">База данных чертежа</param>
  6. /// <param name="value">Числовое значение хендла</param>
  7. /// <returns>Идентификатор объекта или ObjectId.Null при неудаче</returns>
  8. public static ObjectId IdFromHandleValue(this Database db, long value)
  9.     => IdFromHandle(db, new Handle(value));
  10.  
  11. /// <summary>
  12. /// Get ObjectId from the handle of the database object
  13. /// </summary>
  14. /// <param name="db">Database of the drawing</param>
  15. /// <param name="handle">Handle of the object</param>
  16. /// <returns>ObjectId value or ObjectId.Null</returns>
  17. public static ObjectId IdFromHandle(this Database db, Handle handle)
  18. {
  19.     ObjectId ret = ObjectId.Null;
  20.     db?.TryGetObjectId(handle, out ret);
  21.     return ret;
  22. }
  23.  
  24. /// <summary>
  25. /// Проверка типа Id объекта
  26. /// </summary>
  27. /// <typeparam name="T">Тип, на который проверяем</typeparam>
  28. /// <param name="id">Id объекта</param>
  29. /// <param name="allowErased">Допускается объект, который был удален</param>  
  30. /// <returns></returns>
  31. public static bool CheckObjectIdFor<T>
  32.     (this ObjectId id,
  33.     bool allowErased = false) where T : DBObject
  34. {
  35.     RXClass forCheck = RXObject.GetClass(typeof(T));
  36.     return !id.IsNull
  37.         && id.IsValid
  38.         && (allowErased || (!id.IsErased && !id.IsEffectivelyErased))
  39.         && (id.ObjectClass.Equals(forCheck) || id.ObjectClass.IsDerivedFrom(forCheck));
  40. }
  41.  
  42.  

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Database.Handseed очень большое значение.
« Ответ #1 : 24-06-2019, 16:52:57 »
Или есть какой-то фокус, позволяющий быстро пропускать "пустые" участки номеров?
Нет. Судя по всему или этот чертеж был создан не в AutoCAD или создан из dxf-файла, где HANDSEED был установлен. Сам AutoCAD обычно нормально работает с HANDSEED. Обычно команда _WBLOCK всего чертежа позволяет исправить HANDSEED, но при этом вполне возможно, что метки промежуточных объектов тоже будут изменены.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Database.Handseed - очень большое значение.
« Ответ #2 : 24-06-2019, 17:07:38 »
Кстати, однократно проанализировав Database до Handseed ты можешь её исправить - установить Database.Handseed  в правильное значение.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Re: Database.Handseed - очень большое значение.
« Ответ #3 : 24-06-2019, 17:12:56 »
Чертёж Сivil 3D. Я его не сам создавал - прислал пользователь. Скорее всего, и создание и редактирование выполнялось только с использованием Сivil 3D.
Кстати, однократно проанализировав Database до Handseed ты можешь её исправить - установить Database.Handseed  в правильное значение.
Не понял, как? Пройтись по всем числам, попробовав получить ObjectId? И это сбросит Handseed на последнее используемое число?
А, я понял! В смысле, что я могу задать это значение - оно Writeable.

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Re: Database.Handseed - очень большое значение.
« Ответ #4 : 24-06-2019, 17:45:48 »
стати, однократно проанализировав Database до Handseed ты можешь её исправить - установить Database.Handseed  в правильное значение.
Наваял такой код:
Код - C# [Выбрать]
  1. [CommandMethod("FixHandseed")]
  2. public void FixHandseed()
  3. {
  4.     Database db = Application.DocumentManager.MdiActiveDocument.Database;
  5.  
  6.     Handle handseed = db.Handseed;
  7.  
  8.     long handseedTotal = handseed.Value;
  9.     long i = handseedTotal;
  10.     ObjectId currentId;
  11.     do
  12.     {
  13.         currentId = db.IdFromHandleValue(i--);
  14.     } while (!currentId.IsValid);
  15.  
  16.     db.Handseed = new Handle(++i);
  17. }
Цикл do выполняется всего один-два раза. То есть, в чертеже реально есть объекты с такими Handle  :-\

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Database.Handseed - очень большое значение.
« Ответ #5 : 24-06-2019, 17:46:14 »
А, я понял! В смысле, что я могу задать это значение - оно Writeable.
Угу. Есть еще одна мысль для получения HANDSEED. Database.Wblock для создания временной базы и проанализировать её HANDSEED:

Код - C# [Выбрать]
  1. [CommandMethod("GetHandSeed")]
  2. public void MyCommand() // This method can have any name
  3. {
  4.   // Put your command code here
  5.   Document doc = Application.DocumentManager.MdiActiveDocument;
  6.   if (doc == null) return;
  7.   Editor ed = doc.Editor;
  8.   using (Database tmpDb = doc.Database.Wblock())
  9.   {
  10.     ed.WriteMessage($"\nH1 = {doc.Database.Handseed:X}, H2={tmpDb.Handseed:X}");
  11.   }
  12. }

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

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Database.Handseed - очень большое значение.
« Ответ #6 : 24-06-2019, 17:48:02 »
Цикл do выполняется всего один-два раза. То есть, в чертеже реально есть объекты с такими Handle  :-\
Ну тогда возможно был какой-то очень большой чертеж из которого поудаляли 90%
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Re: Database.Handseed - очень большое значение.
« Ответ #7 : 24-06-2019, 18:16:34 »
Мдя... Civil 3D, похоже, очень легко это значение увеличивает! Я сделал такой код для проверки:
Код - C# [Выбрать]
  1. [CommandMethod("Last100Handseeds")]
  2. public void LastHandseeds()
  3. {
  4.     Database db = Application.DocumentManager.MdiActiveDocument.Database;
  5.  
  6.     Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
  7.  
  8.     long handseedValue = db.Handseed.Value;
  9.     long i = handseedValue + 1;
  10.  
  11.     ed.WriteMessage("\nHandseed value: {0}", handseedValue);
  12.  
  13.     ObjectId currentId;
  14.  
  15.     while (!db.IdFromHandleValue(--i).IsValid);
  16.  
  17.     ed.WriteMessage("\nLast effective handle value: {0}", i);
  18.  
  19.     int counter = 0;
  20.  
  21.     do
  22.     {
  23.         ed.WriteMessage
  24.             ("\n{0}) {1} - {2}",
  25.             ++counter,
  26.             (currentId = db.IdFromHandleValue(i--)).ObjectClass.Name,
  27.             i.ToString("X"));                              
  28.     } while (currentId.IsValid && counter <= 100);
  29. }
  30.  
Открыл чертёж - запустил код - чуть сдвинул вид - сохранил. И так три раза. Результаты:
Команда: LAST100HANDSEEDS
Handseed value: 169059631
Last effective handle value: 169059630
1) AcDbXrecord - A13A52D
2) AcDbXrecord - A13A52C
3) AcDbXrecord - A13A52B
4) AcDbXrecord - A13A52A
5) AcDbXrecord - A13A529
6) AcDbXrecord - A13A528
7) AcDbXrecord - A13A527
8) AcDbXrecord - A13A526
9) AcDbXrecord - A13A525
10) AcDbXrecord - A13A524
11) AcDbXrecord - A13A523
12) AcDbXrecord - A13A522
13) AcDbXrecord - A13A521
14) AcDbXrecord - A13A520
15) AcDbXrecord - A13A51F
16) AcDbXrecord - A13A51E
17) AcDbXrecord - A13A51D
18) AeccDbUserDefinedAttributeClassification - A13A51C
19) AeccDbClassNode - A13A51B
20) AcMapGWSUndoRecorder - A13A51A
21) AcDbDimStyleTableRecord - A13A519
22) AcDbFontTableRecord - A13A518
23) AcDbFontTableRecord - A13A517
24) AcDbFontTableRecord - A13A516
25) AcDbImpNonPersistentObjectsCollection - A13A515
26) AecDbNotificationTracker - A13A514
27) AcDbFontTableRecord - A13A513
28) AcDbFontTableRecord - A13A512
29) AcDbFontTableRecord - A13A511
30) AcDbFontTableRecord - A13A510
31) AcDbFontTableRecord - A13A50F
32) AcDbFontTableRecord - A13A50E
33) AcDbFontTableRecord - A13A50D
34) AcDbFontTableRecord - A13A50C
35) AcDbFontTableRecord - A13A50B
36) AcDbFontTableRecord - A13A50A
37) AcDbFontTableRecord - A13A509
38) AcDbFontTableRecord - A13A508
39) AcDbFontTableRecord - A13A507
40) AcDbFontTableRecord - A13A506
41) AcDbVXTableRecord - A13A505
42) AcDbVXTableRecord - A13A504
43) AcDbVXTableRecord - A13A503
44) AcDbVXTable - A13A502
45) AcDbFontTable - A13A501
46) AcRxObject - A13A500

Команда: LAST100HANDSEEDS
Handseed value: 169059678
Last effective handle value: 169059677
1) AcDbXrecord - A13A55C
2) AcDbXrecord - A13A55B
3) AcDbXrecord - A13A55A
4) AcDbXrecord - A13A559
5) AcDbXrecord - A13A558
6) AcDbXrecord - A13A557
7) AcDbXrecord - A13A556
8) AcDbXrecord - A13A555
9) AcDbXrecord - A13A554
10) AcDbXrecord - A13A553
11) AcDbXrecord - A13A552
12) AcDbXrecord - A13A551
13) AcDbXrecord - A13A550
14) AcDbXrecord - A13A54F
15) AcDbXrecord - A13A54E
16) AcDbXrecord - A13A54D
17) AcDbXrecord - A13A54C
18) AeccDbUserDefinedAttributeClassification - A13A54B
19) AeccDbClassNode - A13A54A
20) AcMapGWSUndoRecorder - A13A549
21) AcDbDimStyleTableRecord - A13A548
22) AcDbFontTableRecord - A13A547
23) AcDbFontTableRecord - A13A546
24) AcDbFontTableRecord - A13A545
25) AcDbImpNonPersistentObjectsCollection - A13A544
26) AecDbNotificationTracker - A13A543
27) AcDbFontTableRecord - A13A542
28) AcDbFontTableRecord - A13A541
29) AcDbFontTableRecord - A13A540
30) AcDbFontTableRecord - A13A53F
31) AcDbFontTableRecord - A13A53E
32) AcDbFontTableRecord - A13A53D
33) AcDbFontTableRecord - A13A53C
34) AcDbFontTableRecord - A13A53B
35) AcDbFontTableRecord - A13A53A
36) AcDbFontTableRecord - A13A539
37) AcDbFontTableRecord - A13A538
38) AcDbFontTableRecord - A13A537
39) AcDbFontTableRecord - A13A536
40) AcDbFontTableRecord - A13A535
41) AcDbVXTableRecord - A13A534
42) AcDbVXTableRecord - A13A533
43) AcDbVXTableRecord - A13A532
44) AcDbVXTable - A13A531
45) AcDbFontTable - A13A530
46) AcDbXrecord - A13A52F
47) AcDbXrecord - A13A52E
48) AcDbXrecord - A13A52D
49) AcRxObject - A13A52C

Команда: LAST100HANDSEEDS
Handseed value: 169059732
Last effective handle value: 169059731
1) AcDbXrecord - A13A592
2) AcDbXrecord - A13A591
3) AcDbXrecord - A13A590
4) AcDbXrecord - A13A58F
5) AcDbXrecord - A13A58E
6) AcDbXrecord - A13A58D
7) AcDbXrecord - A13A58C
8) AcDbXrecord - A13A58B
9) AcDbXrecord - A13A58A
10) AcDbXrecord - A13A589
11) AcDbXrecord - A13A588
12) AcDbXrecord - A13A587
13) AcDbXrecord - A13A586
14) AcDbXrecord - A13A585
15) AcDbXrecord - A13A584
16) AcDbXrecord - A13A583
17) AcDbXrecord - A13A582
18) AeccDbUserDefinedAttributeClassification - A13A581
19) AeccDbClassNode - A13A580
20) AcMapGWSUndoRecorder - A13A57F
21) AcDbDimStyleTableRecord - A13A57E
22) AcDbFontTableRecord - A13A57D
23) AcDbFontTableRecord - A13A57C
24) AcDbFontTableRecord - A13A57B
25) AcDbImpNonPersistentObjectsCollection - A13A57A
26) AecDbNotificationTracker - A13A579
27) AcDbFontTableRecord - A13A578
28) AcDbFontTableRecord - A13A577
29) AcDbFontTableRecord - A13A576
30) AcDbFontTableRecord - A13A575
31) AcDbFontTableRecord - A13A574
32) AcDbFontTableRecord - A13A573
33) AcDbFontTableRecord - A13A572
34) AcDbFontTableRecord - A13A571
35) AcDbFontTableRecord - A13A570
36) AcDbFontTableRecord - A13A56F
37) AcDbFontTableRecord - A13A56E
38) AcDbFontTableRecord - A13A56D
39) AcDbFontTableRecord - A13A56C
40) AcDbFontTableRecord - A13A56B
41) AcDbVXTableRecord - A13A56A
42) AcDbVXTableRecord - A13A569
43) AcDbVXTableRecord - A13A568
44) AcDbVXTable - A13A567
45) AcDbFontTable - A13A566
46) AcRxObject - A13A565

То есть, при каждом сохранении-закрытии-открытии чертежа, Civil "накидывает" +50 объектов. Причём, похоже, что накидывает он их всегда в самый конец. Поэтому, легко образуются вот такие "пустоты" из сотен миллионов чисел...

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Database.Handseed - очень большое значение.
« Ответ #8 : 24-06-2019, 18:21:02 »
Дмитрий Загорулькин,
Возникает вопрос в необходимости сканирования всей базы. Если это примитивы, то они в одном из блоков (в том числе ModelSpace/PaperSpace).
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Re: Database.Handseed - очень большое значение.
« Ответ #9 : 24-06-2019, 19:11:27 »
Нет, не примитивы :(
Надо найти настройку, которая хранится в базе данных.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Database.Handseed - очень большое значение.
« Ответ #10 : 24-06-2019, 19:13:44 »
Нет, не примитивы :(
Надо найти настройку, которая хранится в базе данных.
Но у нее же есть владелец?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Re: Database.Handseed - очень большое значение.
« Ответ #11 : 24-06-2019, 19:20:22 »
Пытаюсь как раз найти этого владельца. Для этого надо сперва найти настройку, потом по её OwnerId будет понятно кто владелец. А поиск с таким количеством объектов очень сильно затягивается :(

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Database.Handseed - очень большое значение.
« Ответ #12 : 24-06-2019, 19:40:06 »
Дмитрий Загорулькин,
А Database.Wblock копирует эту настройку в новую базу?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Re: Database.Handseed - очень большое значение.
« Ответ #13 : 24-06-2019, 20:00:11 »
Эх... Оптимизировал свои методы и "сканирование" базы данных выполнилось за несколько десятков секунд!  ::)
В общем, нужные мне настройки оказались в NOD. Так что, проще всего будет оттуда их доставать, а не искать по всей базе!

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Database.Handseed - очень большое значение.
« Ответ #14 : 24-06-2019, 20:01:44 »
Эх... Оптимизировал свои методы и "сканирование" базы данных выполнилось за несколько десятков секунд!  ::)
О! Т.е. в сто раз. Неплохо! :D
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение