В компас3д в меню файл/свойства/атрибуты можно добавить/удалить/изменить дополнительные атрибуты документа
как эти атрибуты прочитать/записать через API 7-ой версии? (ну или 5-ой, но для файлов a3d/m3d)
См CreateAttrIterator
для 3D документа можно еще через IDocument3D::AttributeCollection
спасибо за совет, но как прочитать значения с их помощью все равно не разбрался
в API7 таких функций нет вообще,
CreateAttrIterator - это функции dll есть ее аналог ksCreateAttrIterator
как получить его вроде разобрался,
но как из него получить название атрибута и значения так и не понял :`(
как прочитать значение таки разобрался :) благодаря найденому примеру на форуме
а вот как узнать название атрибута пока неясно...
У атрибута можно получить только номер типа атрибута и ключи
См GetAttrKeysInfo
далее можно использовать ksGetAttrType
Но нужно знать имя библиотеки типов.
спасибо за помощь.
не поможете победить еще один нюанс?
есть пример SDK\Pascal\DELPHIAUTO\step3d2\step3D21.pas
там есть процедура:
procedure GetSetUserParamComponent;
var
part: ksPart;
par: ksUserParam;
item: ksLtVariant;
arr: ksDynamicArray;
par2: ksUserParam;
item2: ksLtVariant;
arr2: ksDynamicArray;
a: double;
b: double;
c: integer;
d: integer;
begin
if iDocument3D.IsDetail then
begin
iKompasObject.ksError('Текущий документ должен быть сборкой');
exit;
end;
part := ksPart( iDocument3D.GetPart(0) ); // первая деталь в сборке
par := ksUserParam( iKompasObject.GetParamStruct(ko_UserParam) );
item := ksLtVariant( iKompasObject.GetParamStruct(ko_LtVariant) );
arr := ksDynamicArray( iKompasObject.GetDynamicArray(LTVARIANT_ARR) );
if ( par = nil ) or ( item = nil ) or ( arr = nil ) or ( part = nil ) then
exit;
par.Init();
par.SetUserArray( arr );
item.Init();
item.doubleVal := 12.12;
arr.ksAddArrayItem( -1, item );
item.Init();
item.DoubleVal := 21.21;
arr.ksAddArrayItem( -1, item );
item.Init();
item.IntVal := 666;
arr.ksAddArrayItem( -1, item );
item.Init();
item.IntVal := 999;
arr.ksAddArrayItem( -1, item );
part.SetUserParam(par); // установка пользовательской структуры
part.Update();
// размер пользовательской структуры
iKompasObject.ksMessage( Format('Размер пользовательской структуры %d', [ part.GetUserParamSize() ] ) );
если я точно этот код копирую в свое тестовое приложение
(в нем переписано только подключение к Kompas - iKompasObject := GetActiveOleObject('KOMPAS.Application.5') as KompasObject;)
то строка :
part.SetUserParam(par);
не срабатывает (возвращает false)
и последующий вызов GetUserParamSize тоже возвращает 0
Пользовательские параметры может записывать только прикладная библиотека. .rtw или .dll
Кроме самой пользовательской информации в параметрах запоминается номер команды, имя библиотеки и путь к библиотеке.
Если их явно не задать то запоминается текущая рабочая библиотека. Но при работе контроллера нет рабочей библиотеки и поэтому параметры не записюваются.
Вы можете код из Контроллера(.exe) перенести в отдельную dll и из контроллера подгрузить данную dll как прикладную библиотеку непосредственно в Компас. Выполнить нужные действия вызывая команды из Вашей dll и выгрузить dll
К томуже код будет работать гораздо быстрее т.к. dll будет находиться в одном адресном пространстве с Компасом.
См функции
KompasObject::ksAttachKompasLibrary
KompasObject::ksExecuteKompasLibraryCommand
KompasObject::ksExecuteKompasLibraryCommandEx
KompasObject::ksGetExternalInterface
KompasObject::ksDetachKompasLibrary
Причем функция KompasObject::ksExecuteKompasLibraryCommandEx позволяет передать в библиотеку интерфейс связи через который можно будет передавать данные из контроллера в библиотеку и из библиотеки в контроллер.
Пример для функций ksAttachKompasLibrary ksExecuteKompasLibraryCommand ksDetachKompasLibrary есть в SDK
вот как оно оказывается 8-)
примера в SDK не нашел к сожалению, но в принципе как подключать и вызывать разобрался и сам.
не ясно только куда и как при использовании ksExecuteKompasLibraryCommandEx(libid,123,MyDispatchData)
( точнее я использую аналог - IApplication.LibraryManager.ProceduresLibraries
- .Execute(123,MyDispatchData))
передается MyDispatchData?
как внутри библиотеки получить к этому объекту доступ?
KompasObject::ksGetExternalInterface
или ksGetExternalInterface
спасибо за помощь
Почему иногда в коде вида:
if ki.ksCreateAttrIterator(ref,0,0,0,0,0) then
begin
variable := 0;
pAttr := ki.ksMoveAttrIterator('F', variable);
while pAttr <> 0 do
begin
k := attr.ksGetAttrKeysInfo(pAttr,k1,k2,k3,k4,tt);
....
иногда не срабатывает attr.ksGetAttrKeysInfo ?
хотя атрибут там точно есть, паролей на него никаких нет..
Вот локализовал глюк, кто нибудь может пояснить - я виноват (в чем?) или компас (как быть?):
var
d1,d2: ksDocument3D;
attr1, attr2: ksAttributeObject;
attrPar1, attrPar2: ksAttributeParam;
pAttr, res, rowsCount, columnsCount: integer;
tip: double;
begin
DeleteFile('c:\temp\d1.m3d');
DeleteFile('c:\temp\d2.m3d');
d1 := ksDocument3D(KompasApp2.Document3D);
if d1.Create(false,true) then
d1.SaveAs('c:\temp\d1.m3d')
else
raise Exception.Create('e1');
d2 := ksDocument3D(KompasApp2.Document3D);
if d2.Create(false,true) then
d2.SaveAs('c:\temp\d2.m3d')
else
raise Exception.Create('e2');
attr1 := ksAttributeObject(KompasApp2.GetAttributeObject);
tip := 2.75033446165000e+011;
attrPar1 := ksAttributeParam(KompasApp2.GetParamStruct(ko_Attribute));
pAttr := attr1.ksCreateAttr(d1.Reference,attrPar1,tip,'C:\Program Files\ASCON\KOMPAS-3D V9\Sys\spds.lat');
if pAttr <> 0 then
begin
res := attr1.ksGetAttrTabInfo(pAttr, rowsCount, columnsCount);
if res <> 0 then
begin
log('error1');
log(KompasApp2.ksStrResult);
end;
end;
attr2 := ksAttributeObject(KompasApp2.GetAttributeObject);
attrPar2 := ksAttributeParam(KompasApp2.GetParamStruct(ko_Attribute));
pAttr := attr2.ksCreateAttr(d2.Reference,attrPar2,tip,'C:\Program Files\ASCON\KOMPAS-3D V9\Sys\spds.lat');
if pAttr <> 0 then
begin
res := attr2.ksGetAttrTabInfo(pAttr, rowsCount, columnsCount);
if res <> 0 then
begin
log('error2');
log(KompasApp2.ksStrResult);
end;
end;
end;
в логе будет ошибка "error2" - почему непонятно :`(
упс, сверху код чуть чуть неправильный.. на самом деле ошибка будет "error1"
вот код:
....
attr1 := ksAttributeObject(KompasApp2.GetAttributeObject);
tip := 2.75033446165000e+011;
attrPar1 := ksAttributeParam(KompasApp2.GetParamStruct(ko_Attribute));
pAttr := attr1.ksCreateAttr(d1.Reference,attrPar1,tip,'C:\Program Files\ASCON\KOMPAS-3D V9\Sys\spds.lat');
if pAttr <> 0 then
begin
res := attr1.ksGetAttrTabInfo(pAttr, rowsCount, columnsCount);
if res = 0 then // <- тут было неверное условие
begin
log('error1');
log(KompasApp2.ksStrResult);
end;
end;
attr2 := ksAttributeObject(KompasApp2.GetAttributeObject);
attrPar2 := ksAttributeParam(KompasApp2.GetParamStruct(ko_Attribute));
pAttr := attr2.ksCreateAttr(d2.Reference,attrPar2,tip,'C:\Program Files\ASCON\KOMPAS-3D V9\Sys\spds.lat');
if pAttr <> 0 then
begin
res := attr2.ksGetAttrTabInfo(pAttr, rowsCount, columnsCount);
if res = 0 then // <- тут было неверное условие
begin
log('error2');
log(KompasApp2.ksStrResult);
end;
end;
и в лог пишется:
error1
Невозможно создать документ. Документ с таким именем уже открыт.