Прикладная библиотека на C++ именно в VisualStudio

Автор Elisey Afanasjev, 29.03.19, 14:20:14

« назад - далее »

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

Denis78

Если верить документации, IPart7 и ksPart - это интерфейс компонента 3D документа.
Достаточно скудное описание.
Прикрепил скриншот, надеюсь, это то, что нужно

IPart7 и ksPart - это два разных интерфейса, их можно трансформировать друг в друга, но они разные.
Api7 и Api5.

p3452

 :sun:  :sun:  :sun:
IPart7 - Интерфейс компонента 3D документа
Part - Компонент исполнения
ksPart и IPart - Компонент сборки (деталь или подсборка)

А теперь смотрим на первую строку Вашего скрина, что там написано:
Тело.png

"Тело", в терминах Компаса, является "компонентом"? - Нет!
Вот поэтому и получаете в коде, то что получаете...
+ Благодарностей: 1

graphdark

Цитата: Rosatom от 24.01.22, 15:22:27Да, все правильно, Нужно открыть деталь, перебрать все ее элементы и прочитать свойства этого элемента.

Я сделал новый, с позволения сказать, чертеж. Это параллелепипед со сторонами 34х56х16, созданный путем выдавливания прямоугольника.

Затем, я переписал свой метод, дабы упростить его (поскольку там, действительно уже "каша"). Теперь выглядит он так:

void CVcprjDlg::OnOpen3D(ksDocument3DPtr& doc)
{
ksPartPtr ksp0 = doc->GetPart(0);            // И опять, к сожалению, здесь возвращается NULL
ksPartPtr ksp;
long i;

if (ksp0 == nullptr)                      // Тогда я решил перебирать все индексы, пока не "наткнусь" на валидный
{
for (i = 1; i < 100000L; ++i)
{
ksp = doc->GetPart(i);
if (ksp)
{
std::wstring dbg(L"Valid: ");
dbg += _tow(i) + L'\n';
OutputDebugStringW((LPCWSTR)dbg.data());  // Однако сюда я так и не попал
break;
}
}
}
std::wstring dbg(L"Finish: ");
dbg += _tow(i) + L'\n';
OutputDebugStringW((LPCWSTR)dbg.data());    // А здесь распечатывается i равное 100000, т.е. цикл закончился, ни одного валидного указателя не найдено
}

Что я делаю не так?
Возможно, GetPart(0) нужно от какого-то иного объекта брать, а не от ksDocument3DPtr? Но я посмотрел, больше такого метода ни у кого нет (кроме как у ksPart, но его получить не получается)

PS Пытался еще использовать метод:
ksPartCollectionPtr pcol = doc->PartCollection(true);
pcol вызвращается равным NULL (хоть true туда передавай, хоть false)

С getpart от 0 до количества деталей-индекс элемента дерева в сборке. -1 топ парт, -2 Нью парт, -3 редактировать деталь, -4 редактировать в сборке. Многие свойства метода part->update ждут, имей ввиду.

graphdark

Цитата: Rosatom от 20.01.22, 15:08:01Получается, я могу взять элемент самого верхнего уровня и он вернет какие-то осмысленные параметры, например, материал ("Сталь 10  ГОСТ 1050-2013") и название ("Деталь"). Перейти же на уровень вниз, чтобы взять другие элементы чертежа, я никак не могу. Как это можно сделать?
Вот по работе на сборке читаю свойства элементов, ну потом их писать буду. Delphi код, но синтаксис +- один.Снимок.PNG
+ Благодарностей: 1

Denis78

Полагаю, я правильно "перевел" Delphi-код на плюсы. Но у меня все равно не работает


void CVcprjDlg::OnOpen3D(ksDocument3DPtr& doc)
{
ksPartPtr ksPart;
ksPartCollectionPtr pCollection = ksPartCollectionPtr(doc->PartCollection(true)); // Вот здесь выражение doc->PartCollection(true) возвращает NULL,
long i;                                                                           // а значит, и pCollection тоже будет NULL

if (pCollection)                                          // Сюда мы, конечно не попадаем
{
long ccount = pCollection->GetCount();
for (i = 0; i < ccount; ++i)
{
ksPart = ksPartPtr(pCollection->GetByIndex(i));
Dbg("i = ", i, (void*)ksPart);
}
}
}

Возможно, это происходит потому, что, как писал p3452, "Тело" не является компонентом.
Как же тогда добраться до этого самого "тела"?

Какой ksPartCollection может быть от детали?
Вам наверное нужно EntityCollection - получить указатель на интерфейс динамического массива объектов заданного типа, выбранных в документе.
+ Благодарностей: 1

Denis78

Пытаюсь использовать EntityCollection.

Согласно документации, ksFeature может быть получен с использованием методов следующих интер­фейсов:
– Интерфейса объекта Дерева построения ksFeatureCollection,
– Интерфейса детали или подсборки в составе сборки ksPart.

Я пытаюсь делать это обоими способами, в начале через ksPart, потом через ksFeatureCollection. В обоих случаях, возвращаются одни null'ы

void CVcprjDlg::OnOpen3D(ksDocument3DPtr& doc)
{
    ksPartPtr topPart = doc->GetPart(-1);                                         // Беру топовую часть, не null
    ksFeaturePtr feature = topPart->GetFeature();                                 // Беру feature, не null

    ksBodyCollectionPtr bodycol = feature->EntityCollection(o3d_bodyCollection);  // NULL
    ksBodyPtr body = feature->EntityCollection(o3d_body);                         // NULL

    ksSketchDefinitionPtr sketch = feature->EntityCollection(o3d_sketch);         // Здесь и sketch, и face, и edge,
    ksFaceDefinitionPtr face = feature->EntityCollection(o3d_face);               // и vertex, всё равно NULL
    ksEdgeDefinitionPtr edge = feature->EntityCollection(o3d_edge);               //
    ksVertexDefinitionPtr vertex = feature->EntityCollection(o3d_vertex);         //
    ksDefaultObjectPtr unk = feature->EntityCollection(o3d_unknown);              // Даже здесь NULL

    // ksFeatureCollection м.б. получее с помощью метода ksDocument3D::FeatureCollection:

    // Здесь первые 4 параметра это key1, key2, key3, key4 - ключи для поиска по ключам либо 0,
    // поскольку мне нужно всё, я их полагаю равными 0
    // numb - номер типа атрибута для поиска по но­меру либо 0, по такой же логике передаю 0
    // objType - тип трехмер­ного объекта. Если objType = o3d_unknown - выдавать все объекты.
    ksFeatureCollectionPtr featureCol = doc->FeatureCollection(0, 0, 0, 0, 0, o3d_unknown);   // Здесь возвращается NULL
    long featureCnt = featureCol->GetCount();
}


graphdark

Цитата: Rosatom от 25.01.22, 11:55:27"перевел" Delphi-код на плюсы. Но у меня все равно не работает
Перевели верно, но как верно заметил Sabahs. Только в документе сборки a3d есть partCollection. Иначе там естественно будет nil. Процедура записи свойств. Снимок.PNG

Denis78

ЦитироватьksDocument3D.EntityCollection

Я на плюсах пишу, на них такое даже не скомпилится(((

Denis78

ЦитироватьПеревели верно, но как верно заметил Sabahs. Только в документе сборки a3d есть partCollection. Иначе там естественно будет nil. Процедура записи свойств.

Хорошо, с этим разобрались, сборки нет, получаем null. Но как мне все-таки получить тело (в моем случае это параллелепипед) и его свойства (координаты, длину, ширину,высоту)?

graphdark

Вы поясните, почему

//-------------------------------------------------------------------------------
// kAPI5.tlb
// ---
#pragma warning( disable : 4278 )
#import "ksConstants.tlb" no_namespace
#import "ksConstants3D.tlb" no_namespace 
#import "kAPI5.tlb" named_guids
#import "kAPI7.tlb" no_namespace named_guids
#pragma warning( once : 4278 )

У меня стал ошибки выдавать нелепые.

Снимок.PNG


Все прописано. Раньше все работало. Мистика.

Снимок.PNG

graphdark

Цитата: Rosatom от 25.01.22, 14:56:56Хорошо, с этим разобрались, сборки нет, получаем null. Но как мне все-таки получить тело (в моем случае это параллелепипед) и его свойства (координаты, длину, ширину,высоту)?
У тела нет свойств. Есть внешние переменные в ksVariableCollection  и в ksVariable. Посмотрите в ту сторону, тоже от ksPart
+ Благодарностей: 1

Цитата: Rosatom от 25.01.22, 14:54:18Я на плюсах пишу, на них такое даже не скомпилится(((
А какая разница?
ksEntityCollectionPtr pEntityCollection = doc->EntityCollection(o3d_body,True); // коллекция тел

Denis78

Цитата: Sabahs от 25.01.22, 15:07:47А какая разница?
ksEntityCollectionPtr pEntityCollection = doc->EntityCollection(o3d_body,True); // коллекция тел

Я пробовал:

ksBodyCollectionPtr bodycol = feature->EntityCollection(o3d_bodyCollection); // true сюда не воткнуть, только один параметр принимает
ksBodyPtr body = feature->EntityCollection(o3d_body);                        // аналогично. И, согласно документации, возвращает ksBodyPtr

И bodycol,и body возвращаются равными NULL

Сейчас попробовал вот что:

ksEntityCollectionPtr unknwn = feature->EntityCollection(o3d_unknown);
long c = unknwn->GetCount();

for (long i = 0; i < c; ++i)
{
    ksEntityPtr e = unknwn->GetByIndex(i);
    short type = e->Gettype();
    BSTR name = e->Getname();
}

GetCount() вернул 26!
Gettype() вернул 6 элементов типа 6 (что бы это ни значило), 12 элементов типа 7, 8 элементов типа 8
Getname() всегда возвращает пустую строку. Я надеялся увидеть что-то вроде "Тел-1", "Тело 1", "Элемент выдавливания 1"

Похоже, опять не то, что нужно

Denis78

Цитата: graphdark от 25.01.22, 15:04:32У тела нет свойств. Есть внешние переменные в ksVariableCollection  и в ksVariable. Посмотрите в ту сторону, тоже от ksPart

Я, наверное, опять что-то не то делаю

ksPartPtr topPart = doc->GetPart(-1);
ksFeaturePtr feature = topPart->GetFeature();
ksVariableCollectionPtr vc = feature->VariableCollection;     // Здесь получаю ksVariableCollection, он не NULL, что хорошо
long vcCnt = vc->GetCount();

А вот vcCnt равен нулю, то есть опять ничего не вытащить

p3452

Может, все-таки, для начала, (хоть немного!) попытаться разобраться в объектной модели Компаса!!!

graphdark

Цитата: Rosatom от 25.01.22, 16:32:16А вот vcCnt равен нулю, то есть опять ничего не вытащить
Снимок.PNG
+ Благодарностей: 1

Denis78

Так тоже попробовал, GetCount() все равно нуль возвращает. Я думаю, я не тот part использую, я единственное, пока что могу, это topPart использовать:

ksPartPtr topPart = doc->GetPart(-1);
ksVariableCollectionPtr vc = ksVariableCollectionPtr(topPart->VariableCollection());
long vcCnt = vc->GetCount();

У вас видимо все несколько иначе. Если я правильно понял, сначала вы берете ksPartCollection из документа-3Д, потом пробегаете по всем ksPart'ам в цикле.

part: ksPart;
pCollection: ksPartCollection;

pCollection := ksPartCollection(Doc3D.PartCollection(true));    // [1]
for i := 0 to pCollection.GetCount - 1 do
begin
  part := ksPart(pCollection.GetByIndex(i);
  VarCol := ksVariableCollection(part.VariableCollection())
...
end

У меня, как мы выяснили общими усилиями, сборки нет, и из всех фигур только один параллелепипед, поэтому и Doc3D.PartCollection(true) в строке [1] возвращает NULL, а дальше все действия бессмысленны.

* * *

По поводу ваших ошибок Е1696 - это не ошибки компилятора, их необязательно фиксить; ошибки компилятора с символа "C" начинаются. Лучше смотреть, что в окне Output выводится. Возможно все строится нормально.
И путь, как мне кажется немного странный: "D:/Source/..."
А что если "натравить" переменную $KOMPAS_SDK на папку "c:\Program Files\ASCON\KOMPAS-3D v20\SDK\"? Ну, или где он у вас установлен.
Еще можно попробовать в пункте "Дополнительные каталоги" нажать кнопку Edit и посмотреть, что в поле "Evaluated value" показывается, возможно, пути как-то путаются (ну, в порядке бреда)