DrawableOverrule и Solid3d

Автор Тема: DrawableOverrule и Solid3d  (Прочитано 19512 раз)

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

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

Оффлайн Алексей КузинАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 116
  • Карма: 8
DrawableOverrule и Solid3d
« : 17-02-2016, 12:57:50 »
использую DrawableOverrule для DuctFitting.

Код - C# [Выбрать]
  1. public override void ViewportDraw(Drawable drawable, ViewportDraw vd)
  2.         {
  3.             Solid3d Solidd = new Solid3d();
  4.             Solidd.CreateBox(100,100,100);//для примера
  5.  
  6.             vd.Geometry.Draw(Solidd);
  7.  
  8.             Solidd.Dispose();
  9.  
  10.             base.ViewportDraw(drawable, vd);
  11.         }

в отображении "2d Wireframe"  всё хорошо. стоит переключиться на "Shaded" или любой другой - солид пропадает и начинает вести себя неадекватно.
« Последнее редактирование: 17-02-2016, 14:12:07 от LmRArtist »

Оффлайн Привалов Дмитрий

  • ADN Club
  • *****
  • Сообщений: 533
  • Карма: 117
Re: DrawableOverrule и Solid3d
« Ответ #1 : 17-02-2016, 13:44:53 »
солид пропадает и начинает вести себя неадекватно.
неадекватно это как?

попробуй
//Solidd.Dispose();

или
base.ViewportDraw(drawable, vd);
Solidd.Dispose();

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: DrawableOverrule и Solid3d
« Ответ #2 : 17-02-2016, 14:01:26 »
LmRArtist
Отформатируй код, как указано у меня в подписи.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Алексей КузинАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 116
  • Карма: 8
Re: DrawableOverrule и Solid3d
« Ответ #3 : 17-02-2016, 14:14:42 »
Цитировать
неадекватно это как?

Например: переключаю на "Shaded" - пропал.   делаю OBJRELUPDATE - появился.   масштабирую, переключаю проекции - пропадает.

перенос Dispose() не помог    :( :(

а если Dispose()  убрать вовсе - проблема вроде как решается. Но не думаю что если убрать dispose() хорошая идея.

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: DrawableOverrule и Solid3d
« Ответ #4 : 17-02-2016, 14:20:49 »
Попробуй вместо:
Код - C# [Выбрать]
  1. vd.Geometry.Draw(Solidd);
использовать:
Код - C# [Выбрать]
  1. Solidd.ViewportDraw(vd);
Скорее всего не поможет и скорее всего это ограничение, которое накладывает DrawableOverrule.
Если подготовишь тестовый проект - отправлю в ADN DevHelp. Возможно они смогут помочь.

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

Оффлайн Алексей КузинАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 116
  • Карма: 8
Re: DrawableOverrule и Solid3d
« Ответ #5 : 17-02-2016, 14:26:24 »
Цитировать
Попробуй вместо:
Код - C# [Выбрать]
vd.Geometry.Draw(Solidd);
использовать:
Код - C# [Выбрать]
Solidd.ViewportDraw(vd);
Скорее всего не поможет и скорее всего это ограничение, которое накладывает DrawableOverrule.

не помогло. перестало отображать даже в "2D Wireframe"

Оффлайн Привалов Дмитрий

  • ADN Club
  • *****
  • Сообщений: 533
  • Карма: 117
Re: DrawableOverrule и Solid3d
« Ответ #6 : 17-02-2016, 14:38:16 »
убрать вовсе - проблема вроде как решается. Но не думаю что если убрать dispose() хорошая идея.
На самом деле Dispose() это несколько сложная тема. Сложнее, чем кажется на первый взгляд.
И описана не очень хорошо.

Для разных объектов:
1 нужно вызывать обязательно
2 можно проигнорировать
3 управляется транзакцией
4 нельзя вызывать, т.к. управляется автокадом.
5 необходимо предотвратить вызов

в твоем случае, возможно 4-5
в 5 случае, возможно нужно вынести из метода. И не вызывать Dispose
static Solid3d Solidd = new Solid3d();

Оффлайн Алексей КузинАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 116
  • Карма: 8
Re: DrawableOverrule и Solid3d
« Ответ #7 : 17-02-2016, 16:22:15 »
добавил cash.

Код - C# [Выбрать]
  1. Dictionary<long, Solid3d> cash = new Dictionary<long, Solid3d>();
  2.  
  3.         public override void ViewportDraw(Drawable drawable, ViewportDraw vd)
  4.         {
  5.             Solid3d Solidd = new Solid3d();
  6.             Solidd.CreateBox(100, 100, 100);//для примера
  7.  
  8.             long key = drawable.Id.Handle.Value;
  9.             if (!cash.ContainsKey(key))
  10.                 cash.Add(key, Solidd);
  11.             else
  12.                 cash[key] = Solidd;
  13.  
  14.             vd.Geometry.Draw(Solidd);
  15.  
  16.             base.ViewportDraw(drawable, vd);
  17.         }

Возникают пропадания когда приближаю/отдаляю объекты.  В остальном вроде работоспособно, спасибо Дмитрию за советы  8)

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: DrawableOverrule и Solid3d
« Ответ #8 : 17-02-2016, 18:31:31 »
Пару замечаний по коду.
1) А почему cash не static?
2) Если уж ты обнаружил, что cash.ContainsKey(key), то зачем вызывать Solidd.CreateBox(100, 100, 100), если этот объект у тебя уже есть в cash и ты можешь им воспользоваться?
3) Вместо drawable.Id.Handle.Value лучше пользоваться drawable.Id (т.е. ObjectId). На случай, когда у тебя открыты несколько чертежей.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: DrawableOverrule и Solid3d
« Ответ #9 : 17-02-2016, 21:22:25 »
Я сделал тестовый проект, записал видео и отправил вопрос в ADN DevHelp.
Подозреваю, что нормально Solid3D может отрисовываться в VisualStyle != 2DWireFrame только в случае если он Database Resident (т.е. содержится в чертеже). В данном случае это не так.
Когда будет ответ - сообщу.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Алексей КузинАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 116
  • Карма: 8
Re: DrawableOverrule и Solid3d
« Ответ #10 : 18-02-2016, 15:15:03 »
Спасибо, Александр.

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: DrawableOverrule и Solid3d
« Ответ #11 : 18-02-2016, 15:22:00 »
Спасибо, Александр.
Хотел у тебя уточнить. У тебя именно так появляются и пропадают "ящики", как у меня на видео:

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

Оффлайн Алексей КузинАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 116
  • Карма: 8
Re: DrawableOverrule и Solid3d
« Ответ #12 : 18-02-2016, 15:41:36 »
Да. именно так как у вас на видео.
Есть подозрение что при scale есть определенные участки (уровни детализации). И нужно сохранять Solid3d в cash для каждого из этих участков. Если вы понимаете о чем речь. Возможно я не прав.

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: DrawableOverrule и Solid3d
« Ответ #13 : 18-02-2016, 15:48:53 »
И нужно сохранять Solid3d в cash для каждого из этих участков.
Ну это был бы уже совсем перебор. И так их плодится слишком много, с учетом того, что в нормальной ситуации в конце ViewportDraw/WorldDraw для них должен вызываться Dispose().
Пока из ADN DevHelp мне предложили при включении/выключении Overruling запускать команду Regen3:
Код - C# [Выбрать]
  1. doc.SendStringToExecute("_REGEN3\n", true, false, false);
На всякий случай попробуй, но думаю что это из другой оперы. А сейчас проверить у меня возможности нет.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Алексей КузинАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 116
  • Карма: 8
Re: DrawableOverrule и Solid3d
« Ответ #14 : 18-02-2016, 16:04:44 »
Цитировать
Ну это был бы уже совсем перебор.
тоже так думаю.

Код - C# [Выбрать]
  1. doc.SendStringToExecute("_REGEN3\n", true, false, false);

REGEN3 спасает конечно ситуацию, если рассматривать вариант когда Solid3d создается каждый раз. в этом случае команда REGEN3 вызывает перерисовку и Solid3d будет подменяться в cash. (к слову для "старого" Solid3d который был в cash вызываю dispose())

Цитировать
при включении/выключении Overruling
не совсем корректно только в этих ситуациях будет вызывать. Желательно чтобы при включенном Overruling корректно работало масштабирование, а оно не всегда вызывает перерисовку...  :-\ :-\ :-\

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: DrawableOverrule и Solid3d
« Ответ #15 : 18-02-2016, 16:26:20 »
REGEN3 спасает конечно ситуацию, если рассматривать вариант когда Solid3d создается каждый раз. в этом случае команда REGEN3 вызывает перерисовку и Solid3d будет подменяться в cash. (к слову для "старого" Solid3d который был в cash вызываю dispose())
Не понял. Ты внутри ViewportDraw вызываешь запуск команды REGEN3? Это не годится в любом случае.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: DrawableOverrule и Solid3d
« Ответ #16 : 18-02-2016, 16:41:19 »
А чем эта команда от обычного REGEN отличается?

Оффлайн Алексей КузинАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 116
  • Карма: 8
Re: DrawableOverrule и Solid3d
« Ответ #17 : 18-02-2016, 16:46:12 »
конечно не внутри.

Вот вариант кода, когда подменяется Solid3d каждый раз.
Код - C# [Выбрать]
  1. static Dictionary<ObjectId, Solid3d> cash = new Dictionary<ObjectId, Solid3d>();
  2.  
  3.         public override void ViewportDraw(Drawable drawable, ViewportDraw vd)
  4.         {
  5.             Solid3d Solidd = new Solid3d();
  6.             Solidd.CreateBox(100, 100, 100);//для примера
  7.  
  8.             ObjectId key = drawable.Id;
  9.             if (!cash.ContainsKey(key))
  10.                 cash.Add(key, Solidd);
  11.             else
  12.             {
  13.                 cash[key].Dispose();
  14.                 cash[key] = Solidd;
  15.             }
  16.  
  17.             vd.Geometry.Draw(Solidd);
  18.  
  19.             base.ViewportDraw(drawable, vd);
  20.         }

В такой ситуации при каждом вызове REGEN3 - запускается перерисовка и вызывается метод ViewportDraw.
Solid3d после вызова REGEN3 появляется. Но стоит масштабировать и Solid3d пропадает.
Именно исходя из этого я начал думать что нужно хранить объекты в памяти для каждого уровня детализации.
Проверил теорию так - сохраняю в памяти все объекты , потому как не нашел способ определения этих уровней детализации.
Код - C# [Выбрать]
  1. static Dictionary<ObjectId, List<Solid3d>> cash = new Dictionary<ObjectId, List<Solid3d>>();
  2.  
  3.         public override void ViewportDraw(Drawable drawable, ViewportDraw vd)
  4.         {
  5.             Solid3d Solidd = new Solid3d();
  6.             Solidd.CreateBox(100, 100, 100);//для примера
  7.  
  8.             ObjectId key = drawable.Id;
  9.             if (!cash.ContainsKey(key))
  10.                 cash.Add(key, new List<Solid3d>());
  11.            
  12.             cash[key].Add(Solidd);
  13.  
  14.             vd.Geometry.Draw(Solidd);
  15.  
  16.             base.ViewportDraw(drawable, vd);
  17.         }

При масштабировании перестал пропадать Solid3d (по крайне мере сколько успел посмотреть до падения Автокада  :D)
этот пример конечно не работоспособен. Сделал чтобы проверить теорию...

Оффлайн Алексей КузинАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 116
  • Карма: 8
Re: DrawableOverrule и Solid3d
« Ответ #18 : 18-02-2016, 16:57:55 »
Цитировать
А чем эта команда от обычного REGEN отличается?

точно не знаю чем именно. Но REGEN3 вызывает перерисовку, а REGEN - нет.

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: DrawableOverrule и Solid3d
« Ответ #19 : 18-02-2016, 17:07:53 »
А чем эта команда от обычного REGEN отличается?
Команда недокументированная. Судя по всему отличие от REGEN в том, что REGEN работает только с примитивами в базе данных, а REGEN3 и с транзитной графикой - заставляет её перерисовываться.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Алексей КузинАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 116
  • Карма: 8
Re: DrawableOverrule и Solid3d
« Ответ #20 : 18-02-2016, 18:36:37 »
Если drawing сохранить, то при масштабировании Solid3d пропадать не будет.

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: DrawableOverrule и Solid3d
« Ответ #21 : 18-02-2016, 19:55:30 »
Если drawing сохранить, то при масштабировании Solid3d пропадать не будет.
Не понял. Поясни о чем ты?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Отмечено как Решение Алексей Кузин 19-02-2016, 11:26:45

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: DrawableOverrule и Solid3d
« Ответ #22 : 19-02-2016, 00:41:10 »
Так. Добрался до компа и проверил что даёт _REGEN3:
Код - C# [Выбрать]
  1. // (C) Copyright 2016 by  
  2. //
  3. using System;
  4. using System.Collections.Generic;
  5. using Autodesk.AutoCAD.Runtime;
  6. using Autodesk.AutoCAD.ApplicationServices;
  7. using Autodesk.AutoCAD.DatabaseServices;
  8. using Autodesk.AutoCAD.Geometry;
  9. using Autodesk.AutoCAD.GraphicsSystem;
  10.  
  11. using Autodesk.AutoCAD.EditorInput;
  12. using AcGi = Autodesk.AutoCAD.GraphicsInterface;
  13.  
  14. // This line is not mandatory, but improves loading performances
  15. [assembly: CommandClass(typeof(Rivilis.MyCommands))]
  16.  
  17. namespace Rivilis
  18. {
  19.   public class MyCommands
  20.   {
  21.     [CommandMethod("S3DOver")]
  22.     public void CmdSimpleOverrule()
  23.     {
  24.       if (_overrule == null)
  25.       {
  26.         _overrule = new Solid3dOverrule();
  27.         Overrule.AddOverrule(RXClass.GetClass(typeof(Circle)), _overrule, false);
  28.       }
  29.       else
  30.       {
  31.         Overrule.RemoveOverrule(RXClass.GetClass(typeof(Circle)), _overrule);
  32.         _overrule = null;
  33.       }
  34.       Application.DocumentManager.MdiActiveDocument.Editor.Regen();
  35.       Application.DocumentManager.MdiActiveDocument.SendStringToExecute("_REGEN3 ", true, false, false);
  36.     }
  37.     private static Solid3dOverrule _overrule = null;
  38.   }
  39.   public class Solid3dOverrule : AcGi.DrawableOverrule
  40.   {
  41.     public Dictionary<ObjectId, Solid3d> cash = null;
  42.  
  43.     public override bool WorldDraw(AcGi.Drawable drawable, AcGi.WorldDraw wd)
  44.     {
  45.       base.WorldDraw(drawable, wd);
  46.       return false;
  47.     }
  48.     public override void ViewportDraw(AcGi.Drawable drawable, AcGi.ViewportDraw vd)
  49.     {
  50.       base.ViewportDraw(drawable, vd);
  51.       if (cash == null) cash = new Dictionary<ObjectId, Solid3d>();
  52.       Solid3d sol = new Solid3d();
  53.       if (!cash.ContainsKey(drawable.Id))
  54.       {
  55.         sol.CreateBox(100, 100, 100);
  56.         Circle pt = drawable as Circle;
  57.         if (pt != null) {
  58.           sol.TransformBy(Matrix3d.Displacement(pt.Center.GetAsVector()));
  59.         }
  60.         cash.Add(drawable.Id, sol);
  61.      }
  62.      else
  63.      {
  64.        sol = cash[drawable.Id];
  65.      }
  66.      vd.Geometry.Draw(sol);
  67.     }
  68.   }
  69. }

Вот видео:


Кубики перестали пропадать. Хм... Проверил в AutoCAD 2015 и 2016 - всё чисто.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Алексей КузинАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 116
  • Карма: 8
Re: DrawableOverrule и Solid3d
« Ответ #23 : 19-02-2016, 11:09:48 »
Цитата: LmRArtist от 18-02-2016, 18:36:37
Если drawing сохранить, то при масштабировании Solid3d пропадать не будет.
Не понял. Поясни о чем ты?

создаем новый drawing - рисуем - появляются пропадания при масштабировании.
Сохраняем drawing.
Переоткрываем его - рисуем, теперь при масштабировании пропадания отсутствуют.
(Повторилось несколько раз, но не всегда это срабатывает) - возможно из-за этого у вас пропадания перестали появляться.

Оффлайн Алексей КузинАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 116
  • Карма: 8
Re: DrawableOverrule и Solid3d
« Ответ #24 : 19-02-2016, 11:26:13 »
Ваш код работает. буду разбираться что у меня не так. Очень странно кстати.

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: DrawableOverrule и Solid3d
« Ответ #25 : 19-02-2016, 14:11:16 »
Задал вопрос почему пропадают Solid3D если вызвать для них Dispose() в WorldDraw/ViewportDraw и получил ожидаемый ответ:
Цитировать
Вы должны хранить Solid3D в памяти. Это ожидаемое (запланированное) поведение. AutoCAD в различных условиях сохраняет Drawable в своем списке для оптимального отображения. Если Solid3D удален из памяти, то AutoCAD не сможет его показать.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Алексей КузинАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 116
  • Карма: 8
Re: DrawableOverrule и Solid3d
« Ответ #26 : 19-02-2016, 14:35:58 »
Всё понятно. Спасибо за помощь.
Кстати при вашем варианте падает автокад, из-за того что для Solid3d не вызывается Dispose().   в Output валит сообщения - "Forgot to call Dispose? (Autodesk.AutoCAD.DatabaseServices.Solid3d): DisposableWrapper"

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: DrawableOverrule и Solid3d
« Ответ #27 : 19-02-2016, 15:30:21 »
Кстати при вашем варианте падает автокад, из-за того что для Solid3d не вызывается Dispose().   в Output валит сообщения - "Forgot to call Dispose? (Autodesk.AutoCAD.DatabaseServices.Solid3d): DisposableWrapper"
Я в курсе. Это лишь тестовый пример. В какой момент вызывать Dispose нужно продумать.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Привалов Дмитрий

  • ADN Club
  • *****
  • Сообщений: 533
  • Карма: 117
Re: DrawableOverrule и Solid3d
« Ответ #28 : 19-02-2016, 15:45:39 »
В какой момент вызывать Dispose нужно продумать.
Еще неплохо бы выяснить чем отличаются:
Application.DocumentManager.MdiActiveDocument.Editor.Regen();
Application.DocumentManager.MdiActiveDocument.SendStringToExecute("_REGEN3 ", true, false, false);
_regen
_redrawall
_regenall
RecordGraphicsModified(true);
...и возможно что-то еще


Слишком много их развелось для "освежения вида".
Можно ли ADN потрясти на этот счет?
....кстати словил еще один случай когда помог только RecordGraphicsModified(true); для отображения правильного цвета, после изменения цвета у размера в 2008 автокаде.

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: DrawableOverrule и Solid3d
« Ответ #29 : 19-02-2016, 15:55:16 »
У таблиц и у размеров, как у сложных объектов, есть еще свои методы обновления. У размера это RecomputeDimensionBlock.

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: DrawableOverrule и Solid3d
« Ответ #30 : 19-02-2016, 16:49:15 »
Можно ли ADN потрясти на этот счет?
Не вижу в этом смысла. Исчерпывающей информации не будет, так что в любом случае приходится экспериментировать.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Алексей КузинАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 116
  • Карма: 8
Re: DrawableOverrule и Solid3d
« Ответ #31 : 19-02-2016, 17:51:13 »
сразу не увидел - у вас в коде всегда создается Solid3d. Из-за этого появляются объекты, для которых нужно вызывать Dispose().
Код - C# [Выбрать]
  1. [CommandMethod("S3DOver")]
  2.         public void CmdSimpleOverrule()
  3.         {
  4.           if (_overrule == null)
  5.           {
  6.             _overrule = new Solid3dOverrule();
  7.             ObjectOverrule.AddOverrule(RXClass.GetClass(typeof(Circle)), _overrule, false);
  8.           }
  9.           else
  10.           {
  11.             ObjectOverrule.RemoveOverrule(RXClass.GetClass(typeof(Circle)), _overrule);
  12.             _overrule = null;
  13.           }
  14.           Application.DocumentManager.MdiActiveDocument.Editor.Regen();
  15.           Application.DocumentManager.MdiActiveDocument.SendStringToExecute("_REGEN3 ", true, false, false);
  16.         }
  17.  
  18.         private static Solid3dOverrule _overrule = null;
  19.  
  20.         public class Solid3dOverrule : Autodesk.AutoCAD.GraphicsInterface.DrawableOverrule
  21.         {
  22.             public Dictionary<ObjectId, Solid3d> cash = null;
  23.  
  24.             public override bool WorldDraw(Autodesk.AutoCAD.GraphicsInterface.Drawable drawable, Autodesk.AutoCAD.GraphicsInterface.WorldDraw wd)
  25.             {
  26.                 base.WorldDraw(drawable, wd);
  27.                 return false;
  28.             }
  29.             public override void ViewportDraw(Autodesk.AutoCAD.GraphicsInterface.Drawable drawable, Autodesk.AutoCAD.GraphicsInterface.ViewportDraw vd)
  30.             {
  31.                 base.ViewportDraw(drawable, vd);
  32.                 if (cash == null) cash = new Dictionary<ObjectId, Solid3d>();
  33.                 Solid3d sol = null;
  34.                 if (!cash.ContainsKey(drawable.Id))
  35.                 {
  36.                     sol = new Solid3d();
  37.                     sol.CreateBox(100, 100, 100);
  38.                     Circle pt = drawable as Circle;
  39.                     if (pt != null)
  40.                     {
  41.                         sol.TransformBy(Matrix3d.Displacement(pt.Center.GetAsVector()));
  42.                     }
  43.                     cash.Add(drawable.Id, sol);
  44.                 }
  45.                 else
  46.                 {
  47.                     sol = cash[drawable.Id];
  48.                 }
  49.                 vd.Geometry.Draw(sol);
  50.             }
  51.         }

~1000 объектов - полёт нормальный.
Так же нужно добавить очистку кеша при удалении объектов и наверное еще ряде случаев, надо продумать.+

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: DrawableOverrule и Solid3d
« Ответ #32 : 21-02-2016, 19:23:10 »
Так же нужно добавить очистку кеша при удалении объектов и наверное еще ряде случаев, надо продумать.+
При удалении объектов я бы не советовал очищать кеш. Причина в том, что команды OOPS, U и UNDO могут восстановить этот объект, а у тебя относящийся к нему Solid3d уже удалён.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Алексей КузинАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 116
  • Карма: 8
Re: DrawableOverrule и Solid3d
« Ответ #33 : 24-02-2016, 15:02:30 »
Небольшой вопрос по команде REGEN3.
Может кто подскажет есть что то подобное, но чтобы не вызывалось для всего дровинга, а конкретно по объектом. В частности Solid3d которых нет в базе.

Оффлайн Привалов Дмитрий

  • ADN Club
  • *****
  • Сообщений: 533
  • Карма: 117
Re: DrawableOverrule и Solid3d
« Ответ #34 : 24-02-2016, 19:04:26 »
Может кто подскажет есть что то подобное, но чтобы не вызывалось для всего дровинга, а конкретно по объектом. В частности Solid3d которых нет в базе.
попробуй вызывать метод RecordGraphicsModified(true);
на объектах, для которых ты добавил Solid3d

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: DrawableOverrule и Solid3d
« Ответ #35 : 24-02-2016, 19:15:45 »
Получил ответ из ADN DevHelp по поводу отличия REGEN и REGEN3. REGEN3 удаляет весь графический кеш и перерисовывает всю геометрию по новой. REGEN оптимизирован чтобы перерисовывать только те примитивы, которые отмечены как измененные.

Ну и вот этот код вроде бы делает то, что делает команда REGEN3 в AutoCAD 2015 и новее:
Код - C# [Выбрать]
  1. Document doc = Application.DocumentManager.MdiActiveDocument;
  2. Autodesk.AutoCAD.GraphicsSystem.Manager mpManager = doc.GraphicsManager;
  3. Autodesk.AutoCAD.GraphicsSystem.KernelDescriptor descriptor =
  4.                   new Autodesk.AutoCAD.GraphicsSystem.KernelDescriptor();
  5. descriptor.addRequirement(Autodesk.AutoCAD.UniqueString.Intern("3D Drawing"));
  6. Autodesk.AutoCAD.GraphicsSystem.GraphicsKernel kernal =
  7.                   Autodesk.AutoCAD.GraphicsSystem.Manager.AcquireGraphicsKernel(descriptor);
  8.  
  9. Autodesk.AutoCAD.GraphicsSystem.Model Model = mpManager.GetDBModel(kernal);
  10.  
  11. Model.Invalidate(Autodesk.AutoCAD.GraphicsSystem.InvalidationHint.InvalidateAll);
  12.  
  13. Application.DocumentManager.MdiActiveDocument.Editor.Regen();
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Привалов Дмитрий

  • ADN Club
  • *****
  • Сообщений: 533
  • Карма: 117
Re: DrawableOverrule и Solid3d
« Ответ #36 : 24-02-2016, 21:46:32 »
REGEN оптимизирован чтобы перерисовывать только те примитивы, которые отмечены как измененные.
RecordGraphicsModified(true) как-раз помечает, что entity изменен и его нужно перерисовать.
По идее после каждого изменения свойства, влияющего на отображение, например цвета, примитив должен помечаться как измененный.
Но это происходит не всегда, возможно недоделки API, или подразумевается особая логика.
Скорее всего DrawableOverrule не помечает примитив как измененный.

Оффлайн bender

  • ADN Club
  • **
  • Сообщений: 62
  • Карма: 4
Re: DrawableOverrule и Solid3d
« Ответ #37 : 06-06-2018, 17:03:11 »
А какова вероятность того, что в нескольких одновременно открытых чертежах будут разные объекты с одинаковым id? Может лучше использовать не id, а handle?

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: DrawableOverrule и Solid3d
« Ответ #38 : 06-06-2018, 17:05:23 »
А какова вероятность того, что в нескольких одновременно открытых чертежах будут разные объекты с одинаковым id?
Насколько мне известно, ObjectId уникально в рамках сессии.
Может лучше использовать не id, а handle?
А вот Handle как раз-таки могут быть одинаковыми в разных чертежах.

Вот тут обсуждали: http://adn-cis.org/forum/index.php?topic=7199.msg21267#msg21267

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: DrawableOverrule и Solid3d
« Ответ #39 : 06-06-2018, 18:17:35 »
А какова вероятность того, что в нескольких одновременно открытых чертежах будут разные объекты с одинаковым id? Может лучше использовать не id, а handle?
А что понимать под id? Если ObjectId, то они уникальны, так как хранят в себе информацию о базе данных: ObjectId.Database
Но уникальность не означает, что их следует сравнивать при помощи '==', так как:
Код - C# [Выбрать]
  1. // Autodesk.AutoCAD.DatabaseServices.ObjectId
  2. public static bool operator ==(ObjectId a, ObjectId b)
  3. {
  4.         return a.m_id == b.m_id;
  5. }
Т.е. сравниваются только числовые значения ObjectId.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн bender

  • ADN Club
  • **
  • Сообщений: 62
  • Карма: 4
Re: DrawableOverrule и Solid3d
« Ответ #40 : 06-06-2018, 19:10:59 »
Цитировать
Но уникальность не означает, что их следует сравнивать при помощи '=='
А что в таком случае будет возвращать для двух ObjectId, у которых одинаковые числовые значения?
Код - C# [Выбрать]
  1. cash.ContainsKey(id)

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: DrawableOverrule и Solid3d
« Ответ #41 : 06-06-2018, 19:12:55 »
Цитировать
Но уникальность не означает, что их следует сравнивать при помощи '=='
А что в таком случае будет возвращать для двух ObjectId, у которых одинаковые числовые значения?
Код - C# [Выбрать]
  1. cash.ContainsKey(id)

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

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: DrawableOverrule и Solid3d
« Ответ #42 : 06-06-2018, 19:14:34 »
Надо смотреть как ContainsKey сравнивает ключи, возможно, что не с помощью ==, а через Equals
https://github.com/Microsoft/referencesource/blob/master/mscorlib/system/collections/generic/dictionary.cs

Код - C# [Выбрать]
  1. public bool ContainsKey(TKey key) {
  2.             return FindEntry(key) >= 0;
  3. }

Код - C# [Выбрать]
  1. private int FindEntry(TKey key) {
  2.             if( key == null) {
  3.                 ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
  4.             }
  5.  
  6.             if (buckets != null) {
  7.                 int hashCode = comparer.GetHashCode(key) & 0x7FFFFFFF;
  8.                 for (int i = buckets[hashCode % buckets.Length]; i >= 0; i = entries[i].next) {
  9.                     if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key)) return i;
  10.                 }
  11.             }
  12.             return -1;
  13.         }

То есть, по хеш-коду и с помощью Equals.

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: DrawableOverrule и Solid3d
« Ответ #43 : 06-06-2018, 19:18:26 »
Надо смотреть как ContainsKey сравнивает ключи, возможно, что не с помощью ==, а через Equals
Не поможет. Я посмотрел все методы ObjectId. Ни один из них не использует сравнение Database:
Извините, вам запрещён просмотр содержимого спойлеров.

Код - C# [Выбрать]
  1. [return: MarshalAs(UnmanagedType.U1)]
  2. public sealed override bool Equals(object obj)
  3. {
  4.         if (!(obj is ObjectId))
  5.         {
  6.                 return false;
  7.         }
  8.         ObjectId objectId = (ObjectId)obj;
  9.         ObjectId objectId2 = this;
  10.         return objectId2.m_id == objectId.m_id;
  11. }
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: DrawableOverrule и Solid3d
« Ответ #44 : 06-06-2018, 19:25:07 »
А зачем нам привязка к базе данных? Андрей же откопал в документации, что в ObjectId ссылается на адрес в памяти. Соответственно, он может быть только один на один объект.

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: DrawableOverrule и Solid3d
« Ответ #45 : 06-06-2018, 19:33:50 »
Андрей же откопал в документации, что в ObjectId ссылается на адрес в памяти. Соответственно, он может быть только один на один объект.
Там всё-таки всё хитрее. Я бы не стал полагаться на это.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: DrawableOverrule и Solid3d
« Ответ #46 : 06-12-2018, 16:41:24 »
Уже несколько раз перечитал всю тему, экспериментирую, но никак не могу нащупать: какой должен быть порядок действий, если объект был изменён?
Вот, например. Есть у нас объект, мы его перерисовали кубиком, кубик поместили в кэш. Теперь при каждой перерисовке мы берём кубик из кэша, а не создаём новый. Но, предположим, что габариты объекта поменялись и теперь надо показывать кубик другого размера. Как поступить в этом случае? Старый кубик из кэша удалять? Или ничего не удалять, а создать просто новый и закинуть в кэш? Вызывать ли команду _REGEN3 при этом?
Что-то никак не могу подружиться с этим механизмом. Постоянно теряется графика, если объект изменять.

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: DrawableOverrule и Solid3d
« Ответ #47 : 06-12-2018, 18:21:03 »
Старый кубик из кэша удалять?
Если он не используется для других примитивов - удалять. И рисовать новый и закидывать в кэш. Думаю что так.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: DrawableOverrule и Solid3d
« Ответ #48 : 06-12-2018, 21:06:02 »
Если сразу удалять, то почему-то возникают проблемы с отображением. Решил не удалять, а помечать как неиспользуемые. Пока что придумал, что удалять их буду в событии Database.DatabaseToBeDestroyed. Попробовал в событии Application.BeginQuit - ловил стабильный фатал. Сейчас работает как надо и вроде как проблем нет.
Немного напрягает, что неиспользуемые объекты будут висеть в памяти пока чертёж не закроют, но пока другого более подходящего момента не придумал.