Получение ссылки на PartLib для болтового соединения

Автор Cyclopentan, 20.07.21, 15:54:46

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

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

Cyclopentan

Коллеги, добрый день!
Появилась задача получить структуру из файла a3d с определёнными свойствами.
С получением свойств сборок из IPart нет проблем, а вот с получением свойств из тел IBody7, которые не входят в сборку, - сложнее.

Для примера есть чертёж (см. вложения). В нём есть один болт, вставленный как стандартное изделие, уголок и 2 болтовых соединения (сделанных в Компас 3D. Моделирование металлоконструкций). Как видно, болтовое соединение представляет собой просто тела в корневой сборке.
Через IPropertyKeeper можно получить коллекцию всех тел в корневой сборке и нужные свойства этих тел:

Object outerProperty;
bool FromSource;
IApplication app = kompas.ksGetApplication7();
IPropertyMng PropMng = (IPropertyMng)app;
IKompasDocument3D doc7 = (IKompasDocument3D)app.ActiveDocument;
IPart7 topPart7 = doc7.TopPart;
ksPart topPart = kompas.TransferInterface(topPart7, 1, 0);
ksBodyCollection Bodies = topPart.BodyCollection();
for (int j = 1; j < Bodies.GetCount(); j++)
{
 ksBody Body = Bodies.GetByIndex(j);
 IBody7 Body7 = (IBody7)kompas.TransferInterface(Body, (int)Kompas6Constants.ksAPITypeEnum.ksAPI7Dual, 0);
 IPropertyKeeper property_keeper = (IPropertyKeeper)Body7;
 property_keeper.GetPropertyValue(PropMng.GetProperty(doc7, "Материал"), out outerProperty, false, out FromSource);
 kompas.ksMessage(outerProperty.ToString());
}

Но! Если глянуть в MetaProductInfo для этих тел из болтового соединения, том там ещё присутствует ссылка на PartLib:

<infObject id="0bfd5e28-b47a-4529-ae3b-814484a8cfd2" type="body" actual="true" isAdditionNum="false" isFirst="true" source="int_model" spUsed="allStyles">
 <property id="name" value="Болт М16-6gx40.135 ГОСТ 22353-77" type="string" />
 <property id="marking">
  <property id="base" value="" type="string" />
  <property id="embodimentDelimiter" value="-" type="string" />
  <property id="embodimentNumber" value="" type="string" />
  <property id="additionalDelimiter" value="." type="string" />
  <property id="additionalNumber" value="" type="string" />
  <property id="documentDelimiter" value=" " type="string" />
  <property id="documentNumber" value="" type="string" />
 </property>
 <property id="SPCSection" format="{$sectionName}">
  <property id="sectionName" value="" type="string" />
  <property id="sectionNumb" value="25" type="int" />
 </property>
 <property id="count" value="1" type="int" />
 <property id="note" value="" type="string" />
 <property id="235833998283" value="0" type="double" />
 <property id="ID_PartLib" value="PART:B46A_182607A282C24D10[Стандартный;Сталь 30Х2НМФА;40;16;27;2]" type="string" />
 <property id="spcObjNumber" value="205797946025.000000" type="string" />
 <property id="mass" value="0.122699" type="double" />
 <property id="material" format="{$name}">
  <property id="name" value="Сталь 10  ГОСТ 1050-2013" type="string" />
  <property id="density" value="7856" type="double" />
  <property id="location" value="" type="string" />
 </property>
 <property id="specRoughSign" value="0" type="int" />
 <property id="specRoughValue" value="" type="string" />
</infObject>


Ни в спецификации, ни в свойствах самих тел в Компасе я такого не нашёл. Вопрос - как через API до этого параметра тела достучаться?

Вират Лакх

Если пройти циклом по всем свойствам, то выдаст или нет?
iPropertyKeeper = API7.IPropertyKeeper(iBody7)
for i in range(iPropertyMng.PropertyCount(iKompasDocument)):
iProperty = iPropertyMng.GetProperty(iKompasDocument, i)
print(i, iProperty.Id, iProperty.Name, iPropertyKeeper.GetPropertyValue(iProperty, 0, True)[1])

Cyclopentan

Угу, уже проверял все свойства - ID_PartLib среди них нет. Вот результат кода со значением полей:

0 | 4 | Обозначение |
1 | 5 | Наименование | Болт М16-6gx40.135 ГОСТ 22353-77
2 | 6 | Количество | 1
3 | 9 | Материал | Сталь 10  ГОСТ 1050-2013
4 | 10 | Плотность | 7855,99999999998
5 | 8 | Масса | 0,122698680094698
6 | 11 | Автор |
7 | 12 | Организация |
8 | 13 | Комментарий |
9 | 14 | Тип объекта | Тело
10 | 15 | Позиция |
11 | 16 | Полное имя файла | C:\Users\user\AppData\Roaming\Local Service\Documents\292713876_292713881_292713864_0\MainAssembly.a3d
12 | 17 | Имя файла | MainAssembly.a3d
13 | 18 | Создан | 29.06.2021 13:28:24
14 | 19 | Последнее изменение | 19.07.2021 14:53:23
15 | 20 | Раздел спецификации |
16 | 21 | Разработал |
17 | 22 | Проверил |
18 | 23 | Утвердил |
19 | 24 | Т. контр. |
20 | 25 | Н. контр. |
21 | 26 | Класс точности |
22 | 37 | Знак неуказанной шероховатости |
23 | 38 | Параметр неуказанной шероховатости |
24 | 50 | Рассекать на разрезах | Да
25 | 2 | Зона |
26 | 7 | Примечание |
27 | 1 | Форматы листов документа |
28 | 55 | Литера |
29 | 56 | Характер работы |
30 | 57 | Подписал |
31 | 59 | Код продукции |
32 | 235833998283 | Длина профиля | 0
33 | 286725271520 | Документ |
34 | 290108629069 | Наименование материала |
35 | 276039607982 | Сечение |
36 | 316618764777 | Эскиз сечения |
37 | 289516577711 | Наименование профиля ГОСТ, ТУ |
38 | 276893548975 | Наименование или марка металла ГОСТ, ТУ |
39 | 174963986747 | Вид изделия |
40 | 302406992401 | Обозначение стандарта |
41 | 173984476184 | Типоразмер |


Собственно, перечень совпадает с локальными свойствами документа, которые открываются по кнопке "Свойства" тела.
Покопавшись в них нашёл, что в Локальные свойства документа можно перекидывать свойства из других внешних библиотек (см. вложение). В одной из них нашёл некий ID PartLib и добавил к локальным свойствам. Но он, зараза, пустой, то в самом компасе для этих тел, что в выгрузке:

42 | 191509213834 | ID PartLib |

Видимо, это не тот параметр, что в MetaProductInfo. Но ведь откуда-то он там берётся.

Slaviation

Добрый день.
Во вложении тест получения ID PartLib для стандартного изделия.
Запускать на активной сборке, имеющей в своем составе  только единственный компонент, вставленный из  PartLib.

Cyclopentan

Добрый день!
Вот от всей души поклон Вам в пояс! Работает!

Вся хитрость была в GetPropertyAdditionalStorage!
Как запустить код на Python немного не сообразил, но переписал всё на C# и вуаля! Всё получилось, у меня есть ID_PartLib!
Ещё раз огромное спасибо и, на всякий случай, получившийся код на С# в копилку знаний, вдруг кому тоже пригодиться.
Код берёт все тела (ksBody) из заданного компонента (IPart7, TopPart если тела лежат в корне чертежа) и выводит для них наименование и ID_PartLib:

Object outerProperty;
Object outerAdditionalProperty;
bool FromSource;
IApplication app = kompas.ksGetApplication7();
IPropertyMng PropMng = (IPropertyMng)app;
IKompasDocument3D doc7 = (IKompasDocument3D)app.ActiveDocument;
IPart7 topPart7 = doc7.TopPart;
ksPart topPart = kompas.TransferInterface(topPart7, 1, 0);
ksBodyCollection Bodies = topPart.BodyCollection();
for (int j = 1; j < Bodies.GetCount(); j++)
{
 ksBody Body = Bodies.GetByIndex(j);
 IBody7 Body7 = (IBody7)kompas.TransferInterface(Body, (int)Kompas6Constants.ksAPITypeEnum.ksAPI7Dual, 0);
 IPropertyKeeper property_keeper = (IPropertyKeeper)Body7;
 _Property iProperty = PropMng.GetProperty(doc7, "Наименование");
 property_keeper.GetPropertyValue(iProperty, out outerProperty, false, out FromSource);
 IUserDataStorage dataStorage = property_keeper.GetPropertyAdditionalStorage(iProperty, false, out FromSource);
 dataStorage.GetObject(0, out outerAdditionalProperty, out Numb);
 kompas.ksMessage("Наименование тела: + "outerProperty.ToString() + ", его ID_PartLib: " + outerAdditionalProperty.ToString());
}

Михаил88


Cyclopentan

Ах если бы. Видел описание, как взять эти параметры из колонок спецификации, но у меня в компасе показывает так:

Михаил88



Cyclopentan

Проверил это поле - вроде галочка стоит. При этом в доп.полях спецификации всё-равно не видно. Но это не суть, главное, через API можно распарсить всю структуру.

Михаил88

я сразу не заметил, что вы написали вставку стандартных изделий делаете через библиотеку металлоконструкций видимо из-за этого так получается. Если вставлять через библиотеку стандартных изделий то наверное у вас эти строчки появятся.

Cyclopentan

Да, Ваша правда, в стандартном компасе всё работает без танцев с бубном и PartLib отображается в спецификации. Но мы, к сожалению, разрабатываем систему как-раз для механического завода, а там вся работа через Металлоконструкции, с которыми постоянно возникают какие-то хитрости.

pr0100

Цитата: Cyclopentan от 21.07.21, 11:45:19Ах если бы. Видел описание, как взять эти параметры из колонок спецификации, но у меня в компасе показывает так:
В вашем стиле спецификации нет строки ID Partlib, ее можно туда добавить

_Валентин_

Добрый день.
я пытаюсь решить схожую задачу. Только мне надо получить значение своего "самописного" свойства.
К сожалению, программист из меня ещё тот. Пишу программы, в основном, комбинируя куски кода из чужих примеров.
Ваша программа, как я думаю, мне должна подойти, но я споткнулся вот на этой строчке. VS упорно выдаёт ошибку, а я не знаю, чем ей помочь.
Что это за Numb? откуда он взялся?

Цитата: Cyclopentan от 21.07.21, 08:43:44 dataStorage.GetObject(0, out outerAdditionalProperty, out Numb);

KrissKross

Просто объявите выше перед использование в методе GetObject переменную Numb без присваивания
также как объявляется переменная FromSource

long Numb;
bool FromSource;
IUserDataStorage dataStorage = property_keeper.GetPropertyAdditionalStorage(iProperty, false, out FromSource);
dataStorage.GetObject(0, out outerAdditionalProperty, out Numb);

_Валентин_

Цитата: KrissKross от 18.12.21, 12:01:11...
Спасибо.
Но, на самом деле, я ошибку допустил чуть выше по коду. Уже нашел её, и исправил. Numb оказался невиновен.
Так что прошу прощения за беспокойство.