Quick export from Compass3D to STL for 3D printing

It so happened that all the free time not occupied with programming, I am “interested” in 3D modeling. Before the relatively free availability of 3D printers, this was nothing more than an abstract hobby. Now, my gnarled models are getting physical.

I design mainly in Compass3D (cheap and cheerful), and especially crocodile there, just export to STL. You need to click “Save As”, choose where to save and stl format, click on advanced save settings, correct these settings so that the model is more “smooth” and only then a miracle will happen. It would seem that this does not have to be done so often, but every time it is incredibly infuriating. Shtosh, let’s automate! A quick google gave an interesting article about this NOT on Habré, but there the solution is not very convenient, and in general C ++. And I can’t jump higher than python. Fortunately, Compass3D has the ability to “script” in this programming language – so let’s try it.

In python in STL

You can automate actions in Compass3D by writing them into a macro using the KOMPAS-macro system, which you must remember to select when installing the application. We press the macro recording, we do the painful procedure of exporting to stl described above, we stop the recording and save the macro code, which, in fact, does nothing. Well, yes, if it worked like that, it would be too simple for an article on Habré. But there is a good preparation that can be supplemented and debugged in the included PyScripter editor. Yes, dear Google, upon request how to debug python scripts in Compass3D please bring to this article, and not where you usually drive there. You need to select the desired file in the Compass-MACRO->Macros list, click “Edit”, and our freshly recorded macro will open.

about the same content
# -*- 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()

We write/edit the code in it and click Run for debugging. What kind of code can be found in the SDK documentation. You didn’t forget to select the SDK when installing Compass3D, didn’t you? 🙂 It is installed in the same directory as the rest of the program files. The documentation is confusing, but everything you need has most likely already been searched and discussed on the developer’s forum. Plus, there are many examples in the archives inside the SDK/Samples directory, though not yet in python. After some wandering, we find the desired SaveAsToAdditionFormat method and get the final macro with something like this code. It should read more or less well from top to bottom – there are even comments!

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()

And how to run it?

I will post the source code on github – in the same place it will be possible to develop it jointly. But another pain was to understand how convenient it is to use. The ideal solution for me is a button on the main toolbar. On YouTube you can find scary videos on how to do this, here we will describe it in words.

The main idea is to add the execution of our script as a third-party utility for Compass3D. We go through the main menu to Applications->Configurator, inside it there is another menu and there you need to select Composition->Add utilities… and specify the path to the python interpreter from the Compass3D distribution. You have it along the path like: “C:\ProgramData\ASCON\KOMPAS-3D\21\Python 3\App\pythonw.exe”.

Now a little lower, in the “Utilities” drop-down, specify any name for the new tool, for example “STL”, so that it will be easier to find it later when adding it to the toolbar. And in the “Parameters” field, specify the full path to the macro file that we wrote above. Next, just close this dialog – it is saved automatically. You can already use this tool through the main menu Applications->Utilities->STL

What about the button on the toolbar?

Most likely, you yourself know how to add it, but still. You need to go to Interface Settings->Panels->Customize, select the “Utilities” section in the “Commands” tab and drag the button with the name of your macro from there to the toolbar you need. Use on health!

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *