Сообщество программистов Autodesk в СНГ

ADN Club => ObjectARX => Тема начата: Gennadiy от 21-07-2016, 15:19:11

Название: Масштаб штриховки
Отправлено: Gennadiy от 21-07-2016, 15:19:11
Добрый день!

Подскажите возможно ли победить такую проблему:
Создаю свой примитив с использованием в нём штриховки.
При установке образца штриховки
Код - C++ [Выбрать]
  1. pHatch->setPattern(AcDbHatch::kPreDefined, _T("ANSI31"));
образец штриховки берётся из разных файлов и зависит от переменной MEASUREMENT,
соответственно плотность штриховки каждый раз меняется, что меня не устраивает.
Допустим поменялась переменная или вставили мой примитив через буфер в другой чертёж, где
MEASUREMENT имеет другое значение, и плотность меняется.

Я пробовал сделать так:
Код - C++ [Выбрать]
  1. // определяю переменную
  2. AcDb::MeasurementValue measure = this->database()->measurement();
  3. if (measure != AcDb::kMetric) this->database()->setMeasurement(AcDb::MeasurementValue::kMetric);
  4. // создание штриховки
  5. ...
  6. // восстановление переменной
  7. if (measure != AcDb::kMetric) this->database()->setMeasurement(mg);

но когда mode->isDragging(), то при определении переменной возникает fatal error в строке
Код - C++ [Выбрать]
  1. AcDb::MeasurementValue mg = this->database()->measurement();

Может можно по другому как то определить систему измерений в чертеже, тогда бы я просто менял масштаб штриховки при создании,
или существуют другие, неизвестные мне, методы? Ведь штриховка autocad не меняется при изменении MEASUREMENT.
Название: Re: Масштаб штриховки
Отправлено: Александр Ривилис от 21-07-2016, 15:30:29
Я пробовал сделать так:
В Custom Entity??? Если да, то в каком методе?
Название: Re: Масштаб штриховки
Отправлено: Александр Ривилис от 21-07-2016, 15:33:00
Ведь штриховка autocad не меняется при изменении MEASUREMENT.
При изменении MEASUREMENT она не меняется, но если копировать её через буфер обмена в другой чертеж с другим MEASUREMENT, то тут и возникает ерунда...
Название: Re: Масштаб штриховки
Отправлено: Александр Ривилис от 21-07-2016, 15:36:18
но когда mode->isDragging(), то при определении переменной возникает fatal error в строке
Код - C++ [Выбрать]

    AcDb::MeasurementValue mg = this->database()->measurement();
А ты проверь чему у тебя в этом случае равно this->database(). Думаю, что NULL, т.к. твой примитив при Dragging не содержится в базе данных. Вероятно нужно смотреть на acdbCurDwg()->measurement();
Название: Re: Масштаб штриховки
Отправлено: Gennadiy от 21-07-2016, 15:53:39
Если заменить this->database() на acdbCurDwg() то все работает как нужно.
Не уверен, правда, что так делать хорошо, но другого выхода не вижу?
Название: Re: Масштаб штриховки
Отправлено: Gennadiy от 21-07-2016, 15:59:09
Не скажется ли такой вызов acdbCurDwg() на производительности, когда у меня будет тысяча таких объектов?
Название: Re: Масштаб штриховки
Отправлено: Александр Ривилис от 21-07-2016, 16:02:45
Не скажется ли такой вызов acdbCurDwg() на производительности, когда у меня будет тысяча таких объектов?
Не смеши меня. acdbCurDwg() - это acdbHostApplicationServices()->workingDatabase - указатель в памяти на AcDbDatabase. По сравнению со всеми остальными операциями получение этого указателя настолько мизерная по времени операция...
Название: Re: Масштаб штриховки
Отправлено: Александр Ривилис от 21-07-2016, 16:06:58
Не скажется ли такой вызов acdbCurDwg() на производительности, когда у меня будет тысяча таких объектов?
На производительности у тебя скажется создание штриховки при mode->isDragging(). Зачем тебе она тебе нужна в этот момент???
Вообще создавать штриховку в worldDraw/viewportDraw - это очень плохой метод (IMHO).
Название: Re: Масштаб штриховки
Отправлено: Gennadiy от 21-07-2016, 16:11:35
На производительности у тебя скажется создание штриховки при mode->isDragging(). Зачем тебе она тебе нужна в этот момент???
Чтобы было красиво!
Вообще создавать штриховку в worldDraw/viewportDraw - это очень плохой метод (IMHO).
А какой метод хороший? Я ,просто, лучшего, по своей неопытности, не придумал?
Название: Re: Масштаб штриховки
Отправлено: Александр Ривилис от 21-07-2016, 16:39:01
Чтобы было красиво!
Я не знаю насколько у тебя сложный примитив и насколько сложный контур штриховки/масштаб штриховки. Если он достаточно сложный, а компьютер недостаточно производительный, то при перетаскивании объекта будет ужасные задержки. В таких случаях принято при перетаскивании рисовать контур (упрощать изображение).
А какой метод хороший? Я ,просто, лучшего, по своей неопытности, не придумал?
Я думаю, что контур штриховки тебе известен заранее. Соотвественно ты можешь заранее создать примитив штриховки, а в worldDraw/viewportDraw его рисовать. Более того, после того как AutoCAD вызывает твой метод subViewportDraw/subWorldDraw штриховка должна оставаться, иначе можно развалить AutoCAD. Из документации:
Цитировать
Warning: When a custom entity implements subWorldDraw() or subViewportDraw(), and if a native entity (e.g., AcDbCircle) is created within the scope of the method, the native entity needs to exist beyond the method’s scope. The variable should be declared in a global or class level, or some level where the object is alive even after exiting the method.
Название: Re: Масштаб штриховки
Отправлено: Александр Ривилис от 21-07-2016, 17:06:31
Ну и еще одна статья на эту тему: http://adn-cis.org/delaem-byistryimi-worlddraw-i-viewportdraw-polzovatelskogo-obekta.html
К ней еще можно добавить немедленный выход из viewportDraw/worldDraw если mode->regenAbort() == true
Название: Re: Масштаб штриховки
Отправлено: Gennadiy от 21-07-2016, 17:14:56
Я не знаю насколько у тебя сложный примитив
Мой примитив это геологическая скважина в профиле. Состоит из внешнего контура и слоёв, заштрихованных каждый своим типом штриховки, ну и плюс всякое оформление.
Выглядит как то так.
(https://s31.postimg.org/cqmzzksmv/Hole.jpg) (https://postimg.org/image/cqmzzksmv/)
Количество слоев (штриховок) каждый раз разное.

Как я понял правильно будет в классе создать динамический массив с AcDHatch и работать с ним.
Создавать его и наполнять в методе dwgInFields, удалять в деструкторе?

Вся проблема в том, что я пока не знаю как правильно создавать и удалять динамические массивы объектов autocad на c++.
Был бы весьма признателен за подсказку!
Название: Re: Масштаб штриховки
Отправлено: Александр Ривилис от 21-07-2016, 17:32:34
Вся проблема в том, что я пока не знаю как правильно создавать и удалять динамические массивы объектов autocad на c++.
Ну например, так:
Код - C++ [Выбрать]
  1. AcDbVoidPtrArray entArr; // на уровне класса
Код - C++ [Выбрать]
  1. // В методе где создаёшь:
  2. AcDbHatch *pHatch1 = new AcDbHatch(...);
  3. AcDbHatch *pHatch2 = new AcDbHatch(...);
  4. //...
  5. entArr.append(pHatch1);
  6. entArr.append(pHatch2);
  7. //...
Код - C++ [Выбрать]
  1. // В методе где удаляешь:
  2. for (int i = 0; i < entArr.length(); i++)
  3. {
  4.    delete (AcRxObject*) entArr[i];
  5. }
  6. entArr.removeAll();
Название: Re: Масштаб штриховки
Отправлено: Александр Ривилис от 24-07-2016, 18:59:00
Как я понял правильно будет в классе создать динамический массив с AcDHatch и работать с ним.
Если у тебя только те штриховки, которые на рисунке (ну или еще аналогичное, но достаточно простые), то я бы на твоём месте вообще отказался от AcDbHatch и самостоятельно бы штриховал рисунок. Гибкости (IMHO) было бы больше.
Название: Re: Масштаб штриховки
Отправлено: Gennadiy от 24-07-2016, 20:05:08
Спасибо, Александр. Я уже так и сделал, потестировав предварительно разные варианты. В результате выиграл во всем, и в производительности и в использовании памяти.
Не хочется начинать новую тему, но назрел ещё один вопрос:

можно ли как то ограничить перемещение грипсы в методе subMoveGripPointsAt, например только
по одной из осей, или в пределах заданной области? Буду признателен за совет.
Название: Re: Масштаб штриховки
Отправлено: Александр Ривилис от 24-07-2016, 20:06:21
Не хочется начинать новую тему, но назрел ещё один вопрос:
А придётся. Создавай тему.