Конвертация плоской детали в dwg

Автор feuer628, 30.01.24, 11:02:13

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

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

feuer628

Добрый день!
Сталкивался ли кто-нибудь с задачей извлечения эскиза из плоской детали и сохранение его в dwg?
Можно даже в cdw (а потом воспользоваться встроенной в компас пакетной конвертицией в dwg)

В идеале, алгоритм такой:
имеем сборочный чертеж, макросом выбираем все детали, каждую деталь, если это возможно (логику тут прикрутить можно разную), сохраняем в dwg, для отправки на ЧПУ.

то есть некоторая автоматизация, чтобы после сборочного чертежа не приходилось многое делать руками, где велика вероятность допустить ошибки (особенно при большом числе компонентов).

Запись макросов включал, но выполнение линий, видимо, не тоже самое что чтение элементов.

Да и дебаг и получение/изучение конкретной переменной дает мало результата.
Компас версии 21, питон в компасе версии Python 3.2.5 (default, May 15 2013, 23:06:03)

Буду благодарен любому куску кода по получению данных из имеющегося сборки/делати.

Вират Лакх

Есть "Экспорт видов cdw-dxf v5" на питоне объемом 255 строк кода, которая выбирает из видов геометрию для dxf с проверкой замкнутости. Обрабатывает текущий, все открытые или указанную папку. Но она продажная. Если Вы сами пишите, то задавайте конкретные вопросы.

feuer628

Если разбить общую задачу на подзадачи, то буду благодарен за следующие куски кода:
- получение списка деталей из сборки
- получение из детали эскиза
- копирование эскиза в dwg/dxf

feuer628

#3
или может кто подскажет как в дебаге понять какая переменная (или тип переменной) какую часть пользовательского/графического интерфейса обозначет.
Например,
kompas_document_3d = kompas_api7_module.IKompasDocument3D(kompas_document)
iDocument3D = kompas_object.ActiveDocument3D()

рассматриваю iDocument3D в дебаге, а понять что это такое не могу)
дебаг говорит, что это экземпляр ksDocument3D, а что это даже https://help.ascon.ru/KOMPAS/21/ru-RU/41_glava3_ekcport_zapis_gruppi_failov.html не подсказывает.
Может где есть литература где расписано соответствие типов питона и элементов из графического интерфейса?

Вират Лакх

ksDocument3D - это тип, он же класс. Его совокупность методов и свойств - это интерфейс объекта. Или ksDocument3D тоже можно назвать интерфейсом. Экземпляр этого типа - это реализация класса, т.е. объект.
Для лучшей читаемости в питоне переменные желательно называть ближе или так же, как тип, например, iKompasDocument3D.
Описание типов смотрим в SDK и библиотеках типов.
https://help.ascon.ru/KOMPAS_SDK/22/ru-RU/index.html
+ Благодарностей: 1

Михаил88

Приложите пример детали, чтобы можно было открыть в К18.1.
 

feuer628

Сохранил для версии 5.11 R03. Надеюсь откроется.
на самом деле конкретная деталь не так важна, так как на ЧПУ можно делать только плоские фигуры, то это всегда какая-то плоская фигура, выдавленная на некоторую толщину.
Для простоты можно использовать цилиндр/куб и прочие элементарные объемные детали...
Добавил скрин для одной из детали.

Михаил88

Цитата: feuer628 от 30.01.24, 11:02:13имеем сборочный чертеж, макросом выбираем все детали,
У Вас 3D модель сборки (.a3d) или сборочный чертеж (.cdw)? Вы бы скинули конкретный пример вот это на входе, вот это на выходе. Можно просто скриншотами даже.

Вират Лакх

Тоже хотел сказать, что не понятно, от чего плясать.
Цитата: feuer628 от 30.01.24, 13:00:54- получение списка деталей из сборки
От вашего kompas_document_3d = kompas_api7_module.IKompasDocument3D(kompas_document)
kompas_document_3d.TopPart.PartsEx(1) # Первые экземпляры вставок компонентов
+ Благодарностей: 1

Михаил88

+ Благодарностей: 1

feuer628

Вот элементарный вариант для простоты:
на входе сборочный чертеж Сборка.a3d (прилагаю и сборку и составные элементы) у него 3 разные детали - дно, большая стенка (2шт), малая стенка (2шт). Скриншот прилагаю

На выходе должно быть 3 чертежа dwg/dxf (дно, большая и малая стенки) для передачи на станок ЧПУ (Скриншот деталей не прилагаю, так как это просто прямоугольники).

Цитата: Михаил88 от 31.01.24, 07:41:41https://forum.ascon.ru/index.php?topic=35243.msg313919#msg313919

Здесь можете почитать как сохранить в dwg.

Спасибо! как дойду до конкретного сохранения буду прилаживать код)
в первую очередь хотел пройтись по деталям и скопировать эскиз из них.

Цитата: Вират Лакх от 31.01.24, 06:58:59Тоже хотел сказать, что не понятно, от чего плясать.От вашего kompas_document_3d = kompas_api7_module.IKompasDocument3D(kompas_document)
kompas_document_3d.TopPart.PartsEx(1) # Первые экземпляры вставок компонентов

спасибо за наводку! реализовал получение путей всех деталей:

import pythoncom
from win32com.client import Dispatch, gencache

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

Documents = application.Documents

# парсит все детали из сборки
def parseDetails(a3d, details):
    kompas_document_3d = kompas_api7_module.IKompasDocument3D(a3d)
    topPart = kompas_document_3d.TopPart
    for component in topPart.PartsEx(0):
        if component.Detail:
            # если это деталь добавляем ее в результирующий массив
            details.append(component.FileName)
        else:
            # иначе это вложенная сборка (можно проверить расширение на всякий...)
            inner_a3d = Documents.Open(component.FileName, False, True)
            parseDetails(inner_a3d, details)
            inner_a3d.Close(0)


#  Открываем документ
kompas_document = Documents.Open("C:/Users/cheremnov/Documents/тетс/Сборка.a3d", False, True)
details = []

# считываем все детали
parseDetails(kompas_document, details)
kompas_document.Close(0)

print(len(details))
for detail in details:
    # тут нужно открыть деталь и извлечь эскиз (на входе имеем путь детали)
    # также где-то тут сделаю логику чтобы одинаковые элементы не добавлялись, а к выходному чертежу добавлялся постфикс: ". 2шт", например
    print(detail)

Осталось извлечь эскиз из детали и сохранить его в dwg/dxf :angel:

Михаил88

#11
А эскиз всегда один? Вы получается не пользуетесь при проектировании листовым телом? А делаете через твердое тело детали?
Зачем вообще извлекать эскиз. Можно сохранить нужный вид детали в чертеж, удалить оформление чертежа и потом сохранить в dwg.

Вират Лакх

На форуме есть готовые, похожие на вашу задачу, программы типа DXF-Auto или как там она правильно называется. Не проще такую приобрести? Или ещё нужно научиться писать под компас самому и ни от кого не зависеть?
PartsEx(0) у вас в коде - будет дольше из-за дублей. Я бы не имена файлов собирал, а интерфейсы. Или сразу же делал dxf. Вы исполнениями пользуетесь? Если да, то к именам нужно добавить индекс исполнения.
Если считать количество, то лучше (быстрее) все равно PartsEx(1) с определением количества вставок. Ну и словарь какой-то нужно собирать по всей сборке. Ещё про имена файлов. Компонент может быть локальным. А может быть вообще тело.

Михаил88

У него детали сделаны твердым телом, здесь упомянутые Вами программы не подходят.

feuer628

Цитата: Михаил88 от 31.01.24, 13:31:58А эскиз всегда один? Вы получается не пользуетесь при проектировании листовым телом? А делаете через твердое тело детали?
Зачем вообще извлекать эскиз. Можно сохранить нужный вид детали в чертеж, удалить оформление чертежа и потом сохранить в dwg.

В моем случае - да. Эскиз всегда один. Не уверен, но с несколькими эскизами уже вряд ли эту делать можно будет вырезать на ЧПУ из плоского листа.
Пока моя компетенция в компасе не дошла до листового тела)
Делаю эскиз и выдавливаю его на нужную толщину.

В целом, вид детали тоже подойдет для моего случая, только как понять какой вид нужен? с максимальной площадью?
Опять таки в моем случае эскиз всегда будет один, то есть не надо делать логику по определению нужного вида. Его можно вытащить оттуда в принципе?


Цитата: Вират Лакх от 31.01.24, 14:08:06На форуме есть готовые, похожие на вашу задачу, программы типа DXF-Auto или как там она правильно называется. Не проще такую приобрести? Или ещё нужно научиться писать под компас самому и ни от кого не зависеть?
PartsEx(0) у вас в коде - будет дольше из-за дублей. Я бы не имена файлов собирал, а интерфейсы. Или сразу же делал dxf. Вы исполнениями пользуетесь? Если да, то к именам нужно добавить индекс исполнения.
Если считать количество, то лучше (быстрее) все равно PartsEx(1) с определением количества вставок. Ну и словарь какой-то нужно собирать по всей сборке. Ещё про имена файлов. Компонент может быть локальным. А может быть вообще тело.

у меня редко бывают некоторые поделки для домашнего использования, цена этой программы не маленькая + Михаил88, говорит она мне может не подойти.

использования PartsEx(0)/PartsEx(1) посмотрю, разберусь. Спасибо!

Михаил88

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

#  Получи константы
kompas6_constants = gencache.EnsureModule("{75C9F5D0-B5B8-4526-8681-9903C567D2ED}", 0, 1, 0).constants

#  Получи 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
documents = application.Documents

kompas_document = application.ActiveDocument
path = kompas_document.Path
kompas_document_3d = kompas_api7_module.IKompasDocument3D(kompas_document)
part7 = kompas_document_3d.TopPart
name = part7.Name

fragment = documents.Add(kompas6_constants.ksDocumentFragment, False)
file_name = path + '\\' + name + '.frw'
fragment.SaveAs(file_name)
fragment.Close(kompas6_constants.kdDoNotSaveChanges)

model_container = kompas_api7_module.IModelContainer(part7)
sketchs = model_container.Sketchs
sketch = sketchs.Sketch(0)
sketch.WriteToFragment(file_name)

Запускать на активной детали 3D. Рядом с деталью будет создан фрагмент внутри будет скопированный эскиз.
Вам остается только пересохранить его в dwg.
+ Благодарностей: 1

Teywl Wind

Цитата: feuer628 от 31.01.24, 15:05:18Пока моя компетенция в компасе не дошла до листового тела)

Очень жаль, потому что на форуме есть готовое решение по сохранению разверток в формате dxf.

https://forum.ascon.ru/index.php?topic=38163.0

Понимаю, что dxf не dwg, но данный формат вроде как читается режущими станками
+ Благодарностей: 1

feuer628

Сделал в итоге то, что планировал - из сборки получаю плоские детали и экспортирую их в папки с разбивкой по толщине.
Для моих целей то, что надо + прокачался в питоне/компасе  :angel:

Спасибо всем за помощь!

Если вдруг кому пригодиться...
#-------------------------------------------------------------------------------
# Name:        AssemblingToDxfExporter
# Purpose:
#
# Author:      cheremnov
#
# Created:    04.02.2024
# Copyright:  (c) cheremnov 2024
#-------------------------------------------------------------------------------

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

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))
kompas6_constants = gencache.EnsureModule("{75C9F5D0-B5B8-4526-8681-9903C567D2ED}", 0, 1, 0).constants
KompasObject = Dispatch('Kompas.Application.5', None, '{E36BC97C-39D6-4402-9C25-C7008A217E02}')
iApplication = Dispatch('KOMPAS.Application.7')
iConverter = iApplication.Converter(KompasObject.ksSystemPath(1) + '\\ImpExp\\dwgdxfExp.rtw') # Конвертер файлов КОМПАС

Documents = application.Documents

details = {}

def outMessage(text):
    print(text)

# парсит все детали из сборки
def parseDetails(a3d):
    kompas_document_3d = kompas_api7_module.IKompasDocument3D(a3d)
    topPart = kompas_document_3d.TopPart
    for component in topPart.PartsEx(0):
        if component.Detail:
            # если это деталь добавляем ее в результирующий массив
            if details.get(component.FileName):
                details[component.FileName] = details[component.FileName] + 1
            else:
                details[component.FileName] = 1
        else:
            # иначе это вложенная сборка (можно проверить расширение на всякий...)
            innerA3d = Documents.Open(component.FileName, False, True)
            parseDetails(innerA3d)
            innerA3d.Close(kompas6_constants.kdDoNotSaveChanges)

def saveFragments(path):
    iConverterParameters = iConverter.ConverterParameters(1) # Получить интерфейс параметров конвертирования (для dxf: command = 1)
    currentAcadFileVersion = iConverterParameters.AcadFileVersion # Сохранить текущую версию формата dxf
    AutoCAD = {2000:4, 2004:5, 2007:6, 2010:7, 2013:8, 2018:9} # Поддерживаемые версии DXF/DWG
    iConverterParameters.AcadFileVersion = AutoCAD[2013] # Версия AutoCAD, в которую осуществляем запись

    for file in details.keys():
        fragmentDocument = Documents.Open(file, False, True)

        kompas_document_3d = kompas_api7_module.IKompasDocument3D(fragmentDocument)
        part7 = kompas_document_3d.TopPart
        detailName = part7.Name
        model_container = kompas_api7_module.IModelContainer(part7)
        # получаем толщину
        extrusions = model_container.Extrusions
        if len(extrusions) != 1:
            outMessage(file + ". В детали больше одной операции выдавливания, сохранение чертежа не выполняется")
            continue
        extrusion = extrusions.Extrusion(0)
        depth = extrusion.Depth(1)
        depthDir = str(depth) + " мм"
        # создание вложенной папки для указания толщины
        pathToSave = os.path.join(path, depthDir)
        if not os.path.isdir(pathToSave):
            os.mkdir(pathToSave)

        # имя фрагмента - <папка для сохранения>/<название детали>.<количество деталей> шт.
        fragmentName = pathToSave + "/" + detailName + "." + str(details[file]) + " шт."
        frwFileName = fragmentName + "frw"


        sketchs = model_container.Sketchs
        if len(sketchs) != 1:
            outMessage(file + ". В детали больше одного эскиза, сохранение чертежа не выполняется")
            continue

        fragment = Documents.Add(kompas6_constants.ksDocumentFragment, False)

        fragment.SaveAs(frwFileName)
        fragment.Close(kompas6_constants.kdDoNotSaveChanges)

        sketch = sketchs.Sketch(0)
        if not sketch.WriteToFragment(frwFileName):
            outMessage(frwFileName + ". Фрагмент не сохранен")
        fragmentDocument.Close(kompas6_constants.kdDoNotSaveChanges)

        iConverter.Convert(frwFileName, fragmentName + "dxf", 1, False) # Процесс конвертации (файл или текущий документ, новый файл, номер команды, диалог)
        # удаляем файл frw
        os.remove(frwFileName)


    iConverterParameters.AcadFileVersion = currentAcadFileVersion # Вернуть текущую версию формата dxf

# ==============================================================================

# берем активную сборку
kompas_document = application.ActiveDocument

if not kompas_document:
    outMessage("Нет активной сборки")
    quit()

if not kompas_document.Name.endswith('.a3d'):
    outMessage("Для экспорта деталей в dxf необходимо открыть сборку '.a3d'")
    quit()

# создаем папку для экспорта чертежей
autocadPaht = kompas_document.Path + "Чертежи для автокада " + datetime.now().strftime("%d.%m.%Y %H.%M.%S")
os.mkdir(autocadPaht)

# считываем все детали
parseDetails(kompas_document)

# сохраняем эскизы из деталей в dxf
saveFragments(autocadPaht)

+ Благодарностей: 1