Как "разбить" сборку на детали?

Автор Denis78, 12.01.23, 14:47:29

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

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

Denis78

Задача такая. Есть сборка (*.a3d), ее нужно разбить на детали и каждую сохранить отдельно в stp-файле.

Казалось бы все просто.Делаем цикл по parts-ам, находим расположение каждой детали, открываем ее (деталь) и конвертим в stp и всё.
Я использовал сборку, поставляемую вместе с компасом, у меня она лежит вот тут:
C:\Program Files\ASCON\KOMPAS-3D v18\Libs\PARTLib\DATA\vault\methods\kompas\3d\Bearings\20821\PLib_Bearing_GOST_20821_712.a3d

Накидал такой код (привожу только суть), пояснения - в коде, в комментариях

void OnOpen3D(ksDocument3DPtr& doc)           // doc - Это сборка
{
    IKompasDocument3DPtr doc3D(newKompasAPI->ActiveDocument);
    DocumentTypeEnum dtype = doc3D->GetDocumentType();
    if (doc3D)
    {
        IPart7Ptr part7(doc3D->GetTopPart());
        if (part7)
        {
            IParts7Ptr parts = part7->GetParts();
            if (parts && dtype == ksDocumentAssembly)
            {
                long cnt = parts->GetCount();
                for (long i = 0; i < cnt; i++)           // цикл по всем деталям
                {
                    IModelObjectPtr mi = parts->GetItem(i);
                    BSTR miname = mi->GetName();         // Здесь будут имена типа "Левое кольцо", "Втулка", "Свободное кольцо" и т.д.
                    IPart7Ptr pi(mi);
                    if (pi)
                    {
                        BSTR fn = pi->GetFileName();  // А вот здесь уже имена файлов деталей (что мне и нужно), при чем с полным путем к ним
// то есть что-то вроде "C:\\Program Files\\ASCON\\KOMPAS-3D v18\\Libs\\PARTLib\\DATA\\vault\\methods\\kompas\\3d\\Bearings\\20821\\PLib_ring_free_GOST_20821_712.m3d"
                        wstring inName(fn);

[1]                     ksDocument3DPtr doc3Di = kompas->Document3D();      // Беру документ, но это все еще сборка, а не отдельная деталь
                        if (doc3Di)
                        {
[2]                         VARIANT_BOOL ret = doc3Di->Create(false, true);  // Создаю новую деталь, при чем в Компасе действительно появляется новый пустой документ
[3]                         ret = doc3Di->Open(inName, 0);                   // А вот здесь все становится плохо, возвращается false, в Компасе пустой документ остается пустым, ничего не открывается
                            ksAdditionFormatParamPtr fp = doc->AdditionFormatParam();
                            fp->Init();
                            fp->format = format_STEP_AP242;
                            fp->SetObjectsOptions(ksD3CODimensions, VARIANT_TRUE);
[4]                         ret = doc3Di->SaveAsToAdditionFormat(outName, fp);  // Что-то сохраняется (файл создается), а что - непонятно
                        }
                    }
                }
            }
        }
    }
}


Резюмирую.
В строке [1] я беру документ, но doc3Di - это все еще, как мне кажется, сборка, а не отдельная деталь.
В строке [2] создается новая деталь, при чем в Компасе действительно появляется новый пустой документ. И вот тут, как мне кажется doc3Di уже должен бы указывать на только что созданный пустой документ (но, похоже, это не так)
В строке [3] я пытаюсь открыть конкретный файл детали (например, PLib_ring_free_GOST_20821_712.m3d). И вот тут-то все и ломается. Функция Open() возвращает false, пустой документ остается пустым, деталь не открывается.
А вот в [4] строчке сохранение проходит (возвращается true). Действительно, появляется stp-файл небольшого размера. Но что именно сохраняется - не ясно. Если открывать сторонней программой - пустой экран. Если Компасом, то загружается вся сборка.

Я так понимаю, беда в следующем. В строке [2] создается пустой документ, но doc3Di все ещё является сборкой, а не созданным документом.
Как получить тогда указатель на созданный документ?
Хотя, возможно дело в другом.

Есть идеи, как это решить?


PS Имя, передаваемое в функцию Open() верное, проверено дебагером несколько раз.

Михаил88

12.01.23, 16:16:32 #1 Последнее редактирование: 12.01.23, 17:10:14 от Михаил88
Цитата: Denis78 от 12.01.23, 14:47:29Есть идеи, как это решить?

# -*- coding: utf-8 -*-
import pythoncom
from win32com.client import Dispatch, gencache

#  Получи константы
kompas6_constants = gencache.EnsureModule("{75C9F5D0-B5B8-4526-8681-9903C567D2ED}", 0, 1, 0).constants
kompas6_constants_3d = gencache.EnsureModule("{2CAF168C-7961-4B90-9DA2-701419BEEFE3}", 0, 1, 0).constants

#  Подключим описание интерфейсов API5
kompas6_api5_module = gencache.EnsureModule("{0422828C-F174-495E-AC5D-D31014DBBE87}", 0, 1, 0)
kompas_object = kompas6_api5_module.KompasObject(
    Dispatch("Kompas.Application.5")._oleobj_.QueryInterface(kompas6_api5_module.KompasObject.CLSID,
                                                            pythoncom.IID_IDispatch))

#  Получи API интерфейсов версии 7
kompas_api7_module = gencache.EnsureModule("{69AC2981-37C0-4379-84FD-5DD2F3C0A520}", 0, 1, 0)
application = kompas_api7_module.IApplication(
    Dispatch("Kompas.Application.7")._oleobj_.QueryInterface(kompas_api7_module.IApplication.CLSID,
                                                            pythoncom.IID_IDispatch))
ks_document3D = kompas_object.Document3D()
#  Получи интерфейс активного документа
kompas_document = application.ActiveDocument
kompas_document_3d = kompas_api7_module.IKompasDocument3D(kompas_document)
iPart7 = kompas_document_3d.TopPart
parts = iPart7.PartsEx(1)
for part in parts:
    filename = part.FileName
    ks_document3D.Open(filename, False)
    additionFormat = ks_document3D.AdditionFormatParam()
    additionFormat.Init()
    additionFormat.format = kompas6_constants_3d.format_STEP
    ks_document3D.SaveAsToAdditionFormat(filename[:-4] + '.stp', additionFormat)
    ks_document3D.close()

проверил, все работает и сохраняет нормально.
+ Благодарностей: 1

Михаил88

Цитата: Denis78 от 12.01.23, 14:47:29В строке [2] создается новая деталь, при чем в Компасе действительно появляется новый пустой документ.

Зачем вы вообще создаете новую деталь? Когда вам нужно просто открыть нужную деталь и конвертировать в stp.
+ Благодарностей: 1

Denis78

А у вас сохраняет именно детали или сборку целиком?
У меня сборку целиком, то есть получается несколько одинаковых по содержанию файлов.
В попытках решить эту проблему мною и было добавлено создание новой детали. Не помогло

Михаил88


Denis78

Я не особо что понимаю в Python, поэтому хочу спросить, смогу ли я данный скрипт запустить у себя?
Запускал из обычной консоли (cmd), но на строчке 23 ему становится плохо.
Подумал, может, оно должно запускаться из какой-то встроенной консоли внутри самого Компаса, о которой я пока ничего не знаю?

PS Сама ошибка
Traceback (most recent call last):
  File "C:/Users/User/Documents/a3d.py", line 23, in <module>
    kompas_document_3d = kompas_api7_module.IKompasDocument3D(kompas_document)
  File "C:\build_tools\Python379\lib\site-packages\win32com\client\__init__.py", line 514, in __init__
    oobj = pythoncom.new(self.CLSID)

Михаил88

запустите этот файл двойным щелчком. Откроется PyScripter. Далее нажимаете Run. Запускаете на активной сборке, stp файлики сохранятся в туже директорию.

P.S. один из способов запуска.