Как правильно организовать панель свойств библиотеки. Мы запускаем библиотеку, и возникает панель свойств, где мы выбираем необходимые действия. В 2D панель вызывается с помощью запроса к системы на получение координат Document2D.ksPlacementEx(). В 3D есть процесс Document3D.UserGetPlacementAndEntity(), но как в нем получить конкретные координаты? В процессе UserGetCursor() нет возможности вызвать панель свойств?
Смотрите IProcessParam - интерфейс параметров процесса и ksRequestInfo3D - интерфейс параметров запроса к системе.
Данный интерфейс позволяет установить параметры процесса указания местоположения точки или объектов (UserGetPlacementAndEntity).
Создал IProcessParam, с необходимыми кнопками, все отлично. Создал ksRequestInfo3D, в нем указал на параметры. Далее вызываю UserGetPlacementAndEntity(). Появляется моя панель. Как можно получить теперь конкретные координаты (X, Y, Z) нажатия курсора? Есть UserGetCursor(), но он не вызывается, если вызвать его из события нажатия на кнопку панели.
Внимательно посмотрите на методы и свойства ksRequestInfo3D.
Координаты XYZ в любой момент можно получить так:
POINT point;
point.x = point.y = 0;
::GetCursorPos( &point );
::ScreenToClient( ( HWND )IDocumentFrame::GetHWND(), &point );
IDocumentFrame::ConvertCoordinates(....)
Обычно это делается в динамической или статической функциях обратной связи.
Получил координаты с помощью ksRequestInfo3D::GetPlacement() в CallBack функции процесса.
ЦитироватьПолучил координаты с помощью ksRequestInfo3D::GetPlacement() в CallBack функции процесса.
Возможно я не прав, но это не текущие 3D координаты курсора.
Это "Интерфейс локальной системы координат (положение объекта)."
Возможно человеку нужно получить именно точку объекта, которые он фильтрует в CallBack функции.
По щелчку я получаю либо необходимый мне объект, выделяя его и выполняя с ним необходимые действия, либо если щелчок мыши был не на объекте, я получаю место куда вставляется новый объект.
Не могу создать макроообъект с помощью ksDocument3D::GetEditMacroObject, хотя получаю макрообъект из NewEntity((short)Obj3dType.o3d_MacroObject). В чем может быть проблема?
ksMacro3DDefinition - смотрите методы.
А есть разница как создавать макрообъект? через ksDocument3D::GetEditMacroObject(таким образом не могу создать) или можно через NewEntity((short)Obj3dType.o3d_MacroObject)?
GetEditMacroObject возвращает указатель на уже существующий редактируемый макроэлемент, нужно через через NewEntity.
ksEntity.Create - Создать.
Для пользовательского редаектирования я так понял необходимо создать ksUserParam и далее SetUserParam(ksUserParams). Для получения ksUserParam применяется KompasObject::GetParamStruct(short structType). Какую именно использовать structType? Там константы только для 2D документов. И я не очень могу понять каким образом я указываю именно функцию для редактирования...
ko_UserParam
Смотрите ksMacro3DDefinition::SetUserParam
Огромное человеческое спасибо, все получилось, буду разбираться дальше.
Никак не могу разобраться с записью пользовательских параметров в 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 девственно пуст...
Где Вы создали массив?
Смотрите CreateArray - создать стандартный или пользовательский динамический массив неопределенной длины.
Создается массив вот тут:
var array = (ksDynamicArray)Kompas.Instance.KompasObject.GetDynamicArray(ldefin2d.LTVARIANT_ARR);
Дело в том что он создается совершенно нормально, я даже читаю из него необходимые данные. Проблема в том что после передачи его в UserParam, а затем в макрообъект, я не могу его получить из макрообъекта.
Внимательно почитайте примечание GetUserParam.
- Если пользовательские данные были сохранены через ksUserParam::SetUserArray, то перед их получением нужно создать UserArray, аналогичный по структуре используемому при сохранении.
То есть длина должна быть одинаковая в ниже приведенной строке Вы создали массив нулевой длины, куда Компасу данные писать?
var ksUserParamsOut = (ksUserParam)Kompas.Instance.KompasObject.GetParamStruct((short)StructType2DEnum.ko_UserParam);
Это я создал параметры для чтения
var ksUserParamsOut = (ksUserParam)Kompas.Instance.KompasObject.GetParamStruct((short)StructType2DEnum.ko_UserParam);
Если судить этому очень странному замечанию, то мне нужно сначала создать массив, а потом его сверху перезаписать функцией (ksDynamicArray) ksUserParamsOut.GetUserArray()? это совсем глупость какая-то получается...
Проверил типы массивов на выходе и входе - сходятся:
ksMessage(array2.ksGetArrayType().ToString());
ksMessage(array.ksGetArrayType().ToString());
Для начала попробуйте создать массив заполненный нулями идентичной длины и в него прочитать.
Так процесс чтения заключается в том что ksUserParam::GetUserArray() А у него в свою очередь возвращаемое значение:
указатель на интерфейс динамического массива ksDynamicArray типа LTVARIANT_ARR. Смысл создавать массив, если он полностью будет заменен на другой указатель.
ksDynamicArray array2 = (ksDynamicArray) ksUserParamsOut.GetUserArray();
А разве array2.ksGetArrayItem(0,variant); не возвращает значение из полученного массива.
Возвращает, но перед тем как вернуть нужно получить сам массив из параметров макрообъекта с помощью функции ksUserParam::GetUserArray(). А эта функция всегда возвращает пустой массив... Хотя исходный массив 100% создается. Видно что-то не так делаю при чтении массива из параметров. Причем запись и чтение из массива без хранения его (массива) в параметрах макрообъекта проходят на ура
Попробуйте так.
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);
Да, заработало. Весьма запутанная система. Во-первых, сначала нужно создать макрообъект командой 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);
Цитата: 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 фиксирует положение только после клика.
Фантом рисует функция обратной связи, и Вам придется не один час посидеть в отладчике, чтобы понять Авторов Вашей проблемы.
Ну я собираюсь фантом рисовать в SetFilterCallBack, установив DynamicFiltering = true, т.е. конкретно в этой функции брать мой макрообъект, менять его параметры, перерисовывать. И для осуществления этого гениального плана осталось только ловить координаты мыши в любой момент времени...
Посмотрите сначала IDocumentFrame::ConvertCoordinates - она возвращает координаты мыши которые Вам нужны. На входе этой функции нужны координаты курсора в оконных координатах, их можно получить функцией API Windows - ::GetCursorPos( &point ), но она возвращает положение курсора мыши в экранных координатах, что бы преобразовать в координаты окна документа используется функция API Windows - ::ScreenToClient( ( HWND )IDocumentFrame::GetHWND(), &point );