Получается, что все свободное время, не занятое программированием, я «увлекаюсь» 3D-моделированием. До того, как 3D-принтеры стали относительно бесплатными, это было не более чем абстрактное хобби. Теперь мои узловатые модели становятся физическими.
Я в основном проектирую в Compass3D (дешево и сердито), и там в основном крокодил, только экспортирую в STL. Нужно нажать на “Сохранить как”, выбрать место сохранения и формат stl, нажать на дополнительные настройки сохранения, подправить эти настройки, чтобы модель была более “гладкой” и только тогда произойдет чудо. Вроде бы и не так часто приходится это делать, но каждый раз невероятно бесит. Штош, давай автоматизируем! Беглый гугл выдал интересную статью на эту тему НЕ на хабре, но там решение не очень практичное, да и вообще С++. И я не могу прыгнуть выше питона. К счастью, в Compass3D есть возможность «скриптовать» на этом языке программирования — так что давайте попробуем.
Python находится в STL
Вы можете автоматизировать действия в Compass3D, записав их в макрос с помощью системы КОМПАС-макро, которую необходимо не забыть выбрать при установке приложения. Нажимаем записать макрос, выполняем утомительную процедуру экспорта в stl, описанную выше, останавливаем запись и сохраняем код макроса, который на самом деле ничего не делает. Ну да, если бы так работало, то было бы слишком просто для статьи на хабре. Но есть хорошая подготовка, которую можно доделать и отладить во включенном редакторе PyScripter. Да, дорогой Google, по запросу как отлаживать скрипты python в Compass3D Пожалуйста, принесите в этот пункт, а не туда, где вы обычно ездите. Вам нужно выбрать нужный файл из списка Компас-МАКРОС->Макросы, нажать “Редактировать”, и откроется наш свежезаписанный макрос.
примерно такое же содержание
# -*- coding: utf-8 -*-
import pythoncom
from win32com.client import Dispatch, gencache
import LDefin2D
import MiscellaneousHelpers as MH
# Подключим константы API Компас
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))
MH.iKompasObject = kompas_object
# Подключим описание интерфейсов API7
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))
MH.iApplication = application
Documents = application.Documents
# Получим активный документ
kompas_document = application.ActiveDocument
kompas_document_3d = kompas_api7_module.IKompasDocument3D(kompas_document)
iDocument3D = kompas_object.ActiveDocument3D()
Пишем/редактируем туда код и нажимаем Run для отладки. Код какого типа можно найти в документации SDK. Вы ведь не забыли выбрать SDK при установке Compass3D? 🙂 Устанавливается в ту же директорию, что и остальные файлы программы. Документация сбивает с толку, но все, что вам нужно, вероятно, уже исследовано и обсуждено на форуме разработчиков. Также в архивах каталога SDK/Samples есть много семплов, но еще не на питоне. После недолгих блужданий находим нужный метод SaveAsToAdditionFormat и получаем финальный макрос с примерно таким кодом. Читаться должно более-менее хорошо сверху вниз – там даже комментарии есть!
import pythoncom
from win32com.client import Dispatch, gencache
import traceback
class StlExport:
def __init__(self):
# Подключим константы API Компас
self.kompas6_constants = gencache.EnsureModule("{75C9F5D0-B5B8-4526-8681-9903C567D2ED}", 0, 1, 0).constants
self.kompas6_constants_3d = gencache.EnsureModule("{2CAF168C-7961-4B90-9DA2-701419BEEFE3}", 0, 1, 0).constants
# Подключим описание интерфейсов API5
self.kompas6_api5_module = gencache.EnsureModule("{0422828C-F174-495E-AC5D-D31014DBBE87}", 0, 1, 0)
self.kompas_object = self.kompas6_api5_module.KompasObject(
Dispatch("Kompas.Application.5")._oleobj_.QueryInterface(
self.kompas6_api5_module.KompasObject.CLSID,
pythoncom.IID_IDispatch
)
)
# Подключим описание интерфейсов API7
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
)
)
# Получим основной объект API и текущий документ
self.application = kompas_api_object.Application
self.doc = self.application.ActiveDocument
# Если открыт документ с 3D моделью пробуем экспортировать ее в stl
self.iDocument3D = self.kompas_object.ActiveDocument3D()
if self.iDocument3D:
self.export_to_stl()
return
# Иначе напишем пользователю, что не шмогла
self.application.MessageBoxEx("Невозможно сохранить этот документ в STL", "", 64)
def export_to_stl(self):
# Будем ловить все ошибки и вываливать их модальным окном пользователю
try:
# Если документ не сохранен - пути к нему нет
if not self.doc.Path:
self.kompas_object.ksMessage('Невозможно экспортировать несохраненный документ')
return
# А если сохранен, то запишем рядом с ним документ .stl с таким же именем
stl_path = "{}{}.stl".format(self.doc.Path, self.doc.Name[:-4])
self.save_as_stl(self.iDocument3D, stl_path)
except Exception:
msg = "При сохранении в STL произошла ошибка:\n\n{}".format(traceback.format_exc())
self.kompas_object.ksMessage(msg)
def save_as_stl(self, doc, resultPath):
# Собственно, воспользуемся API для экспорта в STL с нужными нам параметрами
additionFormat = doc.AdditionFormatParam()
additionFormat.Init() # старт инициализации параметров
additionFormat.format = self.kompas6_constants_3d.format_STL # формат STL
additionFormat.formatBinary = True # true - бинарный формат, false - текстовый формат
additionFormat.lengthUnits = self.kompas6_constants.ksLUnMM # единицы измерения длины, мм (см. ksLengthUnitsEnum)
# Почему именно такие параметры экспорта - можно на YouTube у Соркина найти
additionFormat.step = 0.05 # максимальное линейное отклонение
additionFormat.angle = 3.6 # максимальное угловое отклонение
# additionFormat.length = 15.792824 # максимальная длина ребра
additionFormat.GetObjectsOptions(
self.kompas6_constants_3d.ksD3COSurfaces # ksD3ConverterOptionsEnum - Константы управляющие разрешением на чтение или запись объектов в дополнительные форматы
)
# Далее, осуществляем сам экспорт
result = doc.SaveAsToAdditionFormat(resultPath, additionFormat)
if result:
self.application.MessageBoxEx("Успешно сохранено!\n\n{}".format(resultPath), "", 64)
else:
raise Exception('SaveAsToAdditionFormat returned false')
if __name__ == "__main__":
StlExport()
И как заставить его работать?
Я выложу исходный код на гитхаб – Там же можно будет его совместно развивать. Но другой болью было понимание того, насколько удобно им пользоваться. Идеальное решение для меня — кнопка на главной панели инструментов. На ютубе можно найти страшные видео как это сделать, здесь мы опишем это на словах.
Основная идея заключается в том, чтобы добавить выполнение нашего скрипта в качестве сторонней утилиты для Compass3D. Заходим через главное меню в Applications->Configurator, внутри есть еще одно меню и там надо выбрать Composition->Add Utilities… и указать путь к интерпретатору python дистрибутива Compass3D. У вас это по пути вида: “C:\ProgramData\ASCON\KOMPAS-3D\21\Python 3\App\pythonw.exe”.
Теперь чуть дальше вниз, в выпадающем списке «Утилиты», укажите любое имя для нового инструмента, например «STL», чтобы его было легче найти потом при добавлении на панель инструментов. И в поле «Параметры» указываем полный путь к файлу макроса, который мы написали выше. Затем просто закройте этот диалог — он сохранится автоматически. Вы уже можете использовать этот инструмент через главное меню Приложения->Утилиты->STL
А как насчет кнопки на панели инструментов?
Скорее всего, вы и сами знаете, как его добавить, но все же. Вам нужно зайти в Настройки интерфейса->Панели->Настроить, выбрать раздел «Утилиты» на вкладке «Команды» и перетащить оттуда кнопку с названием вашего макроса на нужную вам панель инструментов. Пользуйтесь на здоровье!