Подетальное сохранение сборки в Stl скрипт на Python

Автор Вячеслав Никонов, 16.03.21, 14:44:03

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

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

Разработка поделилась скриптами на подетальное сохранение сборок в Stl.

Для работы требуется pywin32.

Первый скрипт для сохранения небольших сборок.
Второй для сборок с большим уровнем вложенности с рекурсией для полного обхода в глубину без повторяющихся элементов. Сохраняет только детали, без подсборок.

Можно использовать скрипты для изучения особенностей API.
Sokhranenie_v_Stl.7z

Вират Лакх

Что за подключение к компасу такое замороченное. Кто-то один это написал, и все повторяют.
Создание библиотеки типов через gencache.EnsureModule нормально, а подключение к компасу можно записать так:
API5 = gencache.EnsureModule('{0422828C-F174-495E-AC5D-D31014DBBE87}', 0, 1, 0)
KompasObject = Dispatch('Kompas.Application.5', None, API5.KompasObject.CLSID)
iApplication = Dispatch('Kompas.Application.7') или KompasObject.ksGetApplication7()
Не всегда требуются оба API. Тогда можно выкинуть лишние строки.
В той популярной записи, которая присутствует в представленном коде, само подключение к ранее запущенному компасу или его запуск завален кучей ненужных букв.

"Рекомендации по использованию метода IUnknown::QueryInterface" в SDK для "Pyton" (почему-то без h) написаны тоже в стиле "в соседнюю калитку через Владивосток".
Можно записать по-людски, аналогично другим языкам программирования:
iKompasDocument = iApplication.ActiveDocument
iDrawingDocument = API7.IDrawingDocument(iKompasDocument) # Здесь выполнится QueryInterface
Хорошо бы в SDK еще добавить, что QueryInterface не обязательно выполнять поэтапно/последовательно. В примере это отражено, но тем не менее.

P.S. Накипело ) Неопытные пользователи путаются и не понимают, что пишут. Спрашивают.
+ Благодарностей: 2


Исходный код первого скрипта для сохранения небольших сборок.

# -*- coding: utf-8 -*-

# для корректной работы скрипта должна быть открыта головная сборка, которую требуется покомпонентно
# конвертировать в STL

import os
import pythoncom
from win32com.client import Dispatch, gencache, VARIANT

#  Получи константы
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

#  Получи API интерфейсов версии 5
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)
kompas_api_object = kompas_api7_module.IKompasAPIObject(
    Dispatch("Kompas.Application.7")._oleobj_.QueryInterface(kompas_api7_module.IKompasAPIObject.CLSID,
                                                             pythoncom.IID_IDispatch))
application = kompas_api_object.Application

# application.HideMessage = 2

# фунция конвертации в STL
# см в SDK: SaveAsToAdditionFormat, ksAdditionFormatParam, IAdditionFormatParam
def ConvertToSTL(doc, resultPath):
    additionFormat = doc.AdditionFormatParam()
    additionFormat.Init()                                    # старт инициализации параметров
    additionFormat.format = kompas6_constants_3d.format_STL  # STL
    additionFormat.formatBinary = True                       # true - бинарный формат, false - текстовый формат
    additionFormat.lengthUnits = kompas6_constants.ksLUnMM   # единицы измерения длины, мм (см. ksLengthUnitsEnum)
    additionFormat.step = 0.1                                # максимальное линейное отклонение
    additionFormat.angle = 7.2                               # максимальное угловое отклонение
    additionFormat.length = 15.792824                        # максимальная длина ребра
    additionFormat.GetObjectsOptions(
        kompas6_constants_3d.ksD3COSurfaces)  # ksD3ConverterOptionsEnum - Константы управляющие разрешением на чтение или запись объектов в дополнительные форматы

    doc.SaveAsToAdditionFormat(resultPath, additionFormat)

    return True

Path = "C:\\Enter_path_here\\"      # путь результирующей директории
# пример Path = "D:\\Test\\"

docAssembly = kompas_object.ActiveDocument3D()  # получаем активный документ
mainAssemblyPath = os.path.basename(docAssembly.fileName)           # формируем путь результирующего документа
mainAssemblyResultPath = Path + os.path.splitext(mainAssemblyPath)[0] + ".stl"  # формируем путь результирующего документа

docAssembly.RebuildDocument         # перестраиваем документ

ConvertToSTL(docAssembly, mainAssemblyResultPath)       # конвертация в STL головной сборки

kompas_document = application.ActiveDocument
doc_API7 = kompas_api7_module.IKompasDocument3D(kompas_document)
topPart = doc_API7.TopPart
openDocParam = topPart.GetOpenDocumentParam()
openDocParam.Visible = True     # признак видимости
openDocParam.ReadOnly = False   # признак открытия в режиме Read-Only
openDocParam.ApplyingIndex = 0  # применяемый тип загрузки
parts = kompas_api7_module.IParts7(topPart.Parts)

for i in range (0, parts.Count):
    sourceDoc = parts.Part(i).OpenSourceDocument(openDocParam)   # открытие документа-источника на редактирование

    doc = kompas_object.ActiveDocument3D()
    fileBasename = os.path.basename(doc.fileName)       # формируем путь результирующего документа
    resultPath = Path + os.path.splitext(fileBasename)[0] + ".stl"      # формируем путь результирующего документа

    doc.RebuildDocument

    ConvertToSTL(doc, resultPath)           # конвертация в STL документа-источника

    sourceDoc.Close(0)

Исходный код второго скрипта для сборок с большим уровнем вложенности с рекурсией для полного обхода в глубину без повторяющихся элементов.
# -*- coding: utf-8 -*-

# для корректной работы скрипта должна быть открыта головная сборка, которую требуется покомпонентно
# конвертировать в STL

import os
import pythoncom
from win32com.client import Dispatch, gencache, VARIANT

#  Получи константы
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

#  Получи API интерфейсов версии 5
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)
kompas_api_object = kompas_api7_module.IKompasAPIObject(
    Dispatch("Kompas.Application.7")._oleobj_.QueryInterface(kompas_api7_module.IKompasAPIObject.CLSID,
                                                             pythoncom.IID_IDispatch))
application = kompas_api_object.Application

# application.HideMessage = 2

arr = []

# фунция конвертации в STL
# см в SDK: SaveAsToAdditionFormat, ksAdditionFormatParam, IAdditionFormatParam
def ConvertToSTL(doc, resultPath):
    additionFormat = doc.AdditionFormatParam()
    # print(additionFormat)
    additionFormat.Init()                                    # старт инициализации параметров
    additionFormat.format = kompas6_constants_3d.format_STL  # STL
    additionFormat.formatBinary = True                       # true - бинарный формат, false - текстовый формат
    additionFormat.lengthUnits = kompas6_constants.ksLUnMM   # единицы измерения длины, мм (см. ksLengthUnitsEnum)
    additionFormat.step = 0.1                                # максимальное линейное отклонение
    additionFormat.angle = 7.2                               # максимальное угловое отклонение
    additionFormat.length = 15.792824                        # максимальная длина ребра
    additionFormat.GetObjectsOptions(
        kompas6_constants_3d.ksD3COSurfaces)  # ksD3ConverterOptionsEnum - Константы управляющие разрешением на чтение или запись объектов в дополнительные форматы

    doc.SaveAsToAdditionFormat(resultPath, additionFormat)

    return True

#рекурсивный сбор уникальных документов
def Collect_Sources(topPart):
    file_name = os.path.basename(topPart.FileName)

    if not topPart.Detail:
        sourceDoc = topPart.PartsEx(kompas6_constants_3d.ksUniqueParts)
        for det in sourceDoc:
            arr.append(det.FileName)
        part = topPart.Parts
        for i in range(part.Count):
            Collect_Sources(part.Part(i))

Path = "C:\\Enter_path_here\\"      # путь результирующей директории
# пример Path = "D:\\Test\\"

docAssembly = kompas_object.ActiveDocument3D()
mainAssemblyPath = os.path.basename(docAssembly.fileName)
mainAssemblyResultPath = Path + os.path.splitext(mainAssemblyPath)[0] + ".stl"

docAssembly.RebuildDocument         # перестраиваем документ

ConvertToSTL(docAssembly, mainAssemblyResultPath)       # конвертация в STL головной сборки

kompas_document = application.ActiveDocument
doc_API7 = kompas_api7_module.IKompasDocument3D(kompas_document)
topPart = doc_API7.TopPart
parts = kompas_api7_module.IParts7(topPart.Parts)

Collect_Sources(topPart)

woduplicatesNames = set(arr)

for name in woduplicatesNames:
    fileBasename = os.path.basename(name)
    resultPath = Path + os.path.splitext(fileBasename)[0] + ".stl"
    kompas_document = application.Documents.Open(name, True)

    if kompas_document:
        doc = kompas_object.ActiveDocument3D()

        doc.RebuildDocument

        ConvertToSTL(doc, resultPath)           # конвертация в STL документа

        kompas_document.Close(0)

Исходный код второго скрипта для сборок с большим уровнем вложенности с рекурсией для полного обхода в глубину без повторяющихся элементов. (исправлена ошибка):
# -*- coding: utf-8 -*-
import os
import pythoncom
from win32com.client import Dispatch, gencache, VARIANT

#  Получи константы
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

#  Получи API интерфейсов версии 5
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)
kompas_api_object = kompas_api7_module.IKompasAPIObject(
    Dispatch("Kompas.Application.7")._oleobj_.QueryInterface(kompas_api7_module.IKompasAPIObject.CLSID,
                                                             pythoncom.IID_IDispatch))
application = kompas_api_object.Application

# application.HideMessage = 2

arr = []

Path = "C:\\Enter_path_here\\"      # путь результирующей директории
# пример Path = "D:\\Test\\"

def ConvertToSTL(doc, resultPath):
    additionFormat = doc.AdditionFormatParam()
    # print(additionFormat)
    additionFormat.Init()  # старт инициализации параметров
    additionFormat.format = kompas6_constants_3d.format_STL  # STL
    additionFormat.formatBinary = True  # true - бинарный формат, false - текстовый формат
    additionFormat.lengthUnits = kompas6_constants.ksLUnMM  # единицы измерения длины, мм (см. ksLengthUnitsEnum)
    additionFormat.step = 0.1  # максимальное линейное отклонение
    additionFormat.angle = 7.2  # максимальное угловое отклонение
    additionFormat.length = 15.792824  # максимальная длина ребра
    additionFormat.GetObjectsOptions(
        kompas6_constants_3d.ksD3COSurfaces)  # ksD3ConverterOptionsEnum - Константы управляющие разрешением на чтение или запись объектов в дополнительные форматы

    doc.SaveAsToAdditionFormat(resultPath, additionFormat)

    return True

def Collect_Sources(topPart):
    file_name = os.path.basename(topPart.FileName)

    if not topPart.Detail:
        sourceDoc = topPart.PartsEx(kompas6_constants_3d.ksUniqueParts)
        for det in sourceDoc:
            arr.append(det.FileName)
        part = topPart.Parts
        for i in range(part.Count):
            Collect_Sources(part.Part(i))
    else:
        arr.append(topPart.FileName)


docAssembly = kompas_object.ActiveDocument3D()
mainAssemblyPath = os.path.basename(docAssembly.fileName)
mainAssemblyResultPath = Path + os.path.splitext(mainAssemblyPath)[0] + ".stl"

docAssembly.RebuildDocument  # перестраиваем документ

ConvertToSTL(docAssembly, mainAssemblyResultPath)  # конвертация в STL головной сборки

kompas_document = application.ActiveDocument
doc_API7 = kompas_api7_module.IKompasDocument3D(kompas_document)
topPart = doc_API7.TopPart
parts = kompas_api7_module.IParts7(topPart.Parts)

Collect_Sources(topPart)

woduplicatesNames = set(arr)

for name in woduplicatesNames:
    fileBasename = os.path.basename(name)
    resultPath = Path + os.path.splitext(fileBasename)[0] + ".stl"
    kompas_document = application.Documents.Open(name, True)

    if kompas_document:
        doc = kompas_object.ActiveDocument3D()

        doc.RebuildDocument

        ConvertToSTL(doc, resultPath)  # конвертация в STL документа-источника

        kompas_document.Close(0)
ConvertToSTL_recursive_1.7z