Форум пользователей ПО АСКОН

Профессиональные вопросы => Программирование приложений => Тема начата: gabik от 20.01.13, 13:56:13

Название: Панель свойств в 3D
Отправлено: gabik от 20.01.13, 13:56:13
Как правильно организовать панель свойств библиотеки. Мы запускаем библиотеку, и возникает панель свойств, где мы выбираем необходимые действия. В 2D панель вызывается с помощью запроса к системы на получение координат Document2D.ksPlacementEx(). В 3D есть процесс Document3D.UserGetPlacementAndEntity(), но как в нем получить конкретные координаты? В процессе UserGetCursor() нет возможности вызвать панель свойств?
Название: Re: Панель свойств в 3D
Отправлено: Sabahs от 20.01.13, 14:21:02
Смотрите IProcessParam - интерфейс параметров процесса и ksRequestInfo3D - интерфейс параметров запроса к системе.
Данный интерфейс позволяет установить параметры процесса указания местоположения точки или объектов (UserGetPlacementAndEntity).

Название: Re: Панель свойств в 3D
Отправлено: gabik от 20.01.13, 15:30:02
Создал IProcessParam, с необходимыми кнопками, все отлично. Создал ksRequestInfo3D, в нем указал на параметры. Далее вызываю UserGetPlacementAndEntity(). Появляется моя панель. Как можно получить теперь конкретные координаты (X, Y, Z) нажатия курсора? Есть UserGetCursor(), но он не вызывается, если вызвать его из события нажатия на кнопку панели.
Название: Re: Панель свойств в 3D
Отправлено: Sabahs от 20.01.13, 15:33:39
Внимательно посмотрите на методы и свойства ksRequestInfo3D.
Название: Re: Панель свойств в 3D
Отправлено: PS от 20.01.13, 15:41:30
Координаты XYZ в любой момент можно получить так:
POINT point;
point.x = point.y = 0;
::GetCursorPos( &point );
::ScreenToClient( ( HWND )IDocumentFrame::GetHWND(), &point );
IDocumentFrame::ConvertCoordinates(....)

Обычно это делается в динамической или статической функциях обратной связи.
Название: Re: Панель свойств в 3D
Отправлено: gabik от 20.01.13, 15:56:13
Получил координаты с помощью ksRequestInfo3D::GetPlacement() в CallBack функции процесса.
Название: Re: Панель свойств в 3D
Отправлено: PS от 20.01.13, 19:48:00
ЦитироватьПолучил координаты с помощью ksRequestInfo3D::GetPlacement() в CallBack функции процесса.
Возможно я не прав, но это не текущие 3D координаты курсора.
Это "Интерфейс локальной системы координат (положение объекта)."
Название: Re: Панель свойств в 3D
Отправлено: Sabahs от 20.01.13, 23:02:03
Возможно человеку нужно получить именно точку объекта, которые он фильтрует в CallBack функции.
Название: Re: Панель свойств в 3D
Отправлено: gabik от 21.01.13, 07:49:46
По щелчку я получаю либо необходимый мне объект, выделяя его и выполняя с ним необходимые действия, либо если щелчок мыши был не на объекте, я получаю место куда вставляется новый объект.
Название: Re: Панель свойств в 3D
Отправлено: gabik от 23.01.13, 08:30:49
Не могу создать макроообъект с помощью ksDocument3D::GetEditMacroObject, хотя получаю макрообъект из NewEntity((short)Obj3dType.o3d_MacroObject). В чем может быть проблема?
Название: Re: Панель свойств в 3D
Отправлено: Sabahs от 23.01.13, 08:47:04
ksMacro3DDefinition - смотрите методы.
Название: Re: Панель свойств в 3D
Отправлено: gabik от 23.01.13, 10:19:54
А есть разница как создавать макрообъект? через ksDocument3D::GetEditMacroObject(таким образом не могу создать) или можно через NewEntity((short)Obj3dType.o3d_MacroObject)?
Название: Re: Панель свойств в 3D
Отправлено: Sabahs от 23.01.13, 10:29:03
GetEditMacroObject возвращает указатель на уже существующий редактируемый макроэлемент, нужно через через NewEntity.
ksEntity.Create - Создать.

Название: Re: Панель свойств в 3D
Отправлено: gabik от 23.01.13, 12:06:34
Для пользовательского редаектирования я так понял необходимо создать ksUserParam и далее SetUserParam(ksUserParams). Для получения ksUserParam применяется KompasObject::GetParamStruct(short structType). Какую именно использовать structType? Там константы только для 2D документов. И я не очень могу понять каким образом я указываю именно функцию для редактирования...
Название: Re: Панель свойств в 3D
Отправлено: Sabahs от 23.01.13, 12:19:21
ko_UserParam
Смотрите ksMacro3DDefinition::SetUserParam
Название: Re: Панель свойств в 3D
Отправлено: gabik от 23.01.13, 12:54:25
Огромное человеческое спасибо, все получилось, буду разбираться дальше.
Название: Re: Панель свойств в 3D
Отправлено: gabik от 24.01.13, 20:10:19
Никак не могу разобраться с записью пользовательских параметров в 3D макрообъект. Вот сделал элементарнейший пример:
Для начала создаю пользовательские параметры, где создаю массив и записываю в него одно число, пусть 10:

var ksUserParams = (ksUserParam)Kompas.Instance.KompasObject.GetParamStruct((short)StructType2DEnum.ko_UserParam);
ksUserParams.Init();
var array = (ksDynamicArray)Kompas.Instance.KompasObject.GetDynamicArray(ldefin2d.LTVARIANT_ARR);
var variant = (ksLtVariant)Kompas.Instance.KompasObject.GetParamStruct((short)StructType2DEnum.ko_LtVariant);
variant.Init();
variant.doubleVal = 10;
array.ksAddArrayItem(-1, variant);
ksUserParams.SetUserArray(array);

Передаю их в макрообъект:

macro3DDef.SetUserParam(ksUserParams);

Теперь попробую сразу же их прочитать:

var ksUserParamsOut = (ksUserParam)Kompas.Instance.KompasObject.GetParamStruct((short)StructType2DEnum.ko_UserParam);
macro3DDef.GetUserParam(ksUserParamsOut);
ksDynamicArray array2 = (ksDynamicArray) ksUserParamsOut.GetUserArray();

И ничего не читается. array2 девственно пуст...
Название: Re: Панель свойств в 3D
Отправлено: Sabahs от 24.01.13, 20:27:12
Где Вы создали массив?
Смотрите CreateArray - создать стандартный или пользовательский динамический массив неопределенной длины.
Название: Re: Панель свойств в 3D
Отправлено: gabik от 24.01.13, 20:39:41
Создается массив вот тут:

var array = (ksDynamicArray)Kompas.Instance.KompasObject.GetDynamicArray(ldefin2d.LTVARIANT_ARR);

Дело в том что он создается совершенно нормально, я даже читаю из него необходимые данные. Проблема в том что после передачи его в UserParam, а затем в макрообъект, я не могу его получить из макрообъекта.
Название: Re: Панель свойств в 3D
Отправлено: Sabahs от 24.01.13, 20:41:54
Внимательно почитайте примечание GetUserParam.
- Если пользовательские данные были сохранены через ksUserParam::SetUserArray, то перед их получением нужно создать UserArray, аналогичный по структуре используемому при сохранении.
То есть длина должна быть одинаковая в ниже приведенной строке Вы создали массив нулевой длины, куда Компасу данные писать?
var ksUserParamsOut = (ksUserParam)Kompas.Instance.KompasObject.GetParamStruct((short)StructType2DEnum.ko_UserParam);
Название: Re: Панель свойств в 3D
Отправлено: gabik от 24.01.13, 21:02:47
Это я создал параметры для чтения
var ksUserParamsOut = (ksUserParam)Kompas.Instance.KompasObject.GetParamStruct((short)StructType2DEnum.ko_UserParam);

Если судить этому очень странному замечанию, то мне нужно сначала создать массив, а потом его сверху перезаписать функцией (ksDynamicArray) ksUserParamsOut.GetUserArray()? это совсем глупость какая-то получается...
Проверил типы массивов на выходе и входе - сходятся:

ksMessage(array2.ksGetArrayType().ToString());
ksMessage(array.ksGetArrayType().ToString());
Название: Re: Панель свойств в 3D
Отправлено: Sabahs от 24.01.13, 21:05:47
Для начала попробуйте создать массив заполненный нулями идентичной длины и в него прочитать.
Название: Re: Панель свойств в 3D
Отправлено: gabik от 24.01.13, 21:21:08
Так процесс чтения заключается в том что ksUserParam::GetUserArray() А у него в свою очередь возвращаемое значение:

указатель на интерфейс динамического массива ksDynamicArray типа LTVARIANT_ARR. Смысл создавать массив, если он полностью будет заменен на другой указатель.



Название: Re: Панель свойств в 3D
Отправлено: Sabahs от 24.01.13, 21:29:06
ksDynamicArray array2 = (ksDynamicArray) ksUserParamsOut.GetUserArray();
А разве array2.ksGetArrayItem(0,variant); не возвращает значение из полученного массива.
Название: Re: Панель свойств в 3D
Отправлено: gabik от 24.01.13, 21:37:24
Возвращает, но перед тем как вернуть нужно получить сам массив из параметров макрообъекта с помощью функции  ksUserParam::GetUserArray(). А эта функция всегда возвращает пустой массив... Хотя исходный массив 100% создается. Видно что-то не так делаю при чтении массива из параметров. Причем запись и чтение из массива без хранения его (массива) в параметрах макрообъекта проходят на ура
Название: Re: Панель свойств в 3D
Отправлено: Sabahs от 24.01.13, 22:14:13
Попробуйте так.
var ksUserParamsOut = (ksUserParam)Kompas.Instance.KompasObject.GetParamStruct((short)StructType2DEnum.ko_UserParam);
var array = (ksDynamicArray)Kompas.Instance.KompasObject.GetDynamicArray(ldefin2d.LTVARIANT_ARR);
var variant = (ksLtVariant)Kompas.Instance.KompasObject.GetParamStruct((short)StructType2DEnum.ko_LtVariant);
variant.Init();
variant.doubleVal = 0;
array.ksAddArrayItem(-1, variant);
ksUserParamsOut.SetUserArray(array);
macro3DDef.GetUserParam(ksUserParamsOut);
ksDynamicArray array2 = (ksDynamicArray) ksUserParamsOut.GetUserArray();
array2.ksGetArrayItem(0,variant);
Название: Re: Панель свойств в 3D
Отправлено: gabik от 25.01.13, 10:05:26
Да, заработало. Весьма запутанная система. Во-первых, сначала нужно создать макрообъект командой Create(), а затем уже прикреплять к объекту параметры. Во-вторых, при чтении параметров из макрообъектов, необходимо создание идентичного ksUserParam, с идентичным внутренним массивом параметров.
Таким образом, при создании макрообъекта:

// Создаем макрообъект
_macroObject.Create();
// Создаем параметры объекта для записи.
macroParam = (ksUserParam)Kompas.Instance.KompasObject.GetParamStruct((short)StructType2DEnum.ko_UserParam);
macroParam.Init();
// Массив для сохранения пользовательских данных.
var array = (ksDynamicArray)Kompas.Instance.KompasObject.GetDynamicArray(ldefin2d.LTVARIANT_ARR);
var variant = (ksLtVariant)Kompas.Instance.KompasObject.GetParamStruct((short)StructType2DEnum.ko_LtVariant);
variant.Init();
variant.doubleVal = _rodParam.Height;
array.ksAddArrayItem(-1, variant);
// Устанавлиаем массив в параметры
macroParam.SetUserArray(array);
// Записываем параметры в макрообъект
macro3DDef.SetUserParam(_macroParam);

Далее, при чтении параметров из макрообъекта:

// Создаем параметры макрообъекта для чтения.
macroParam = (ksUserParam)Kompas.Instance.KompasObject.GetParamStruct((short)StructType2DEnum.ko_UserParam);
macroParam.Init();
// Создаем массив пользовательских параметров (Обязательно должен быть идентична массиву при записи)
var array = (ksDynamicArray)Kompas.Instance.KompasObject.GetDynamicArray(ldefin2d.LTVARIANT_ARR);
var variant2 = (ksLtVariant)Kompas.Instance.KompasObject.GetParamStruct((short)StructType2DEnum.ko_LtVariant);
variant2.Init();
variant2.doubleVal = 0;
array.ksAddArrayItem(-1, variant2);
// Устанавливаем массив в макропараметры
_macroParam.SetUserArray(array);
// И только теперь читаем параметры из макрообъекта
macro3DDefinition.GetUserParam(_macroParam);
// После чего получаем доступ к необходимым данным
array.ksGetArrayItem(0, variant2);
Название: Re: Панель свойств в 3D
Отправлено: gabik от 26.01.13, 19:05:08
Цитата: PS от 20.01.13, 15:41:30
Координаты XYZ в любой момент можно получить так:
POINT point;
point.x = point.y = 0;
::GetCursorPos( &point );
::ScreenToClient( ( HWND )IDocumentFrame::GetHWND(), &point );
IDocumentFrame::ConvertCoordinates(....)

Обычно это делается в динамической или статической функциях обратной связи.
А вот теперь мне понадобились текущие координаты мыши. Для создания фантома 3D макрообъекта в процессе его вставки. Можно чуть поподробней? Что за функции GetCursorPos, ScreenToClient? В SDK  ничего о них не нашел. Как это можно реализовать в Automation? ksRequestInfo3D::GetPlacement фиксирует положение только после клика.
Название: Re: Панель свойств в 3D
Отправлено: Sabahs от 26.01.13, 19:10:58
Фантом рисует функция обратной связи, и Вам придется не один час посидеть в отладчике, чтобы понять Авторов Вашей проблемы.
Название: Re: Панель свойств в 3D
Отправлено: gabik от 26.01.13, 19:16:03
Ну я собираюсь фантом рисовать в SetFilterCallBack, установив DynamicFiltering = true, т.е. конкретно в этой функции брать мой макрообъект, менять его параметры, перерисовывать. И для осуществления этого гениального плана осталось только ловить координаты мыши в любой момент времени...
Название: Re: Панель свойств в 3D
Отправлено: PS от 26.01.13, 21:42:31
Посмотрите сначала IDocumentFrame::ConvertCoordinates - она возвращает координаты мыши которые Вам нужны. На входе этой функции нужны координаты курсора в оконных координатах, их можно получить функцией API Windows  - ::GetCursorPos( &point ), но она возвращает положение курсора мыши в экранных координатах, что бы преобразовать в координаты окна документа используется функция API Windows - ::ScreenToClient( ( HWND )IDocumentFrame::GetHWND(), &point );