Скрипт на поиск непараметризованных объектов

Автор Вячеслав Никонов, 15.04.21, 14:42:31

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

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

Разработка поделилась скриптами по поиску непараметризованных объектов в чертежах. Это размеры с ручным вводом, обозначения без привязки к объекту и подобное.

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

В архиве два скрипта.
Первый скрипт запускается на одном чертеже.
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 = Dispatch('Kompas.Application.5', None, kompas6_api5_module.KompasObject.CLSID)

#  Получи API интерфейсов версии 7
kompas_api7_module = gencache.EnsureModule("{69AC2981-37C0-4379-84FD-5DD2F3C0A520}", 0, 1, 0)
kompas_api_object = kompas_object.ksGetApplication7()

application = kompas_api_object.Application


# application.HideMessage = kompas6_constants.ksHideMessageNo

# dimension_type - тип объекта для поиска, см. в DrawingObjectTypeEnum
# view - вид
def Dimensions_selector(dimension_type, view):
    iDrawingContainer = kompas_api7_module.IDrawingContainer(view)
    lineDimensions = iDrawingContainer.Objects(dimension_type)

    if isinstance(lineDimensions, tuple):
        for dimension in lineDimensions:
            drawingObject = kompas_api7_module.IDrawingObject(dimension)
            drawingObject1 = kompas_api7_module.IDrawingObject1(drawingObject)

            if bool(drawingObject1.Constraints):
                continue
            else:
                chooseMng.Choose(dimension)


iDocument2D = kompas_object.ActiveDocument2D()
iDocument = application.ActiveDocument
iKompasDocument2D = kompas_api7_module.IKompasDocument2D(iDocument)
iKompasDocument2D1 = kompas_api7_module.IKompasDocument2D1(iKompasDocument2D)
# iSelectionManager = iKompasDocument2D1.SelectionManager

viewsAndLayersManager = iKompasDocument2D.ViewsAndLayersManager
views = viewsAndLayersManager.Views

chooseMng = iKompasDocument2D1.ChooseManager

i = 0

dimension_type = [kompas6_constants.ksDrLDimension, kompas6_constants.ksDrADimension, kompas6_constants.ksDrDDimension,
                  kompas6_constants.ksDrRDimension, kompas6_constants.ksDrRBreakDimension, kompas6_constants.ksDrBase,
                  kompas6_constants.ksDrWPointer, kompas6_constants.ksDrCut, kompas6_constants.ksDrLeader,
                  kompas6_constants.ksDrPosLeader,
                  kompas6_constants.ksDrBrandLeader, kompas6_constants.ksDrMarkerLeader,
                  kompas6_constants.ksDrTolerance, kompas6_constants.ksDrMacro, kompas6_constants.ksDrLBreakDimension,
                  kompas6_constants.ksDrABreakDimension,
                  kompas6_constants.ksDrOrdinateDimension, kompas6_constants.ksDrArcDimension,
                  kompas6_constants.ksDrChangeLeader, kompas6_constants.ksDrRemoteElement,
                  kompas6_constants.ksDrMarkOnLeader,
                  kompas6_constants.ksDrMarkOnLine, kompas6_constants.ksDrMarkInsideForm]

while i < views.Count:
    view = views.View(i)

    # для всех типов объектов
    # Dimensions_selector(kompas6_constants.ksAllObj, view)

    # для объектов, заданных в dimension_type из DrawingObjectTypeEnum
    for condition in dimension_type:
        Dimensions_selector(condition, view)

    i += 1
Второй для пакетной проверки (для нескольких чертежей).
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 = Dispatch('Kompas.Application.5', None, kompas6_api5_module.KompasObject.CLSID)

#  Получи API интерфейсов версии 7
kompas_api7_module = gencache.EnsureModule("{69AC2981-37C0-4379-84FD-5DD2F3C0A520}", 0, 1, 0)
kompas_api_object = kompas_object.ksGetApplication7()

application = kompas_api_object.Application

# если потребуется гасить диалоги, то раскомментарить строку ниже
# application.HideMessage = kompas6_constants.ksHideMessageNo

# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# путь к рабочей директории вставлять сюда
path = r"C:\Users\spect\Desktop\Пример"
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

result = []

# dimension_type - тип объекта для поиска, см. в DrawingObjectTypeEnum
# view - вид
def Dimensions_selector(dimension_type, view):
    iDrawingContainer = kompas_api7_module.IDrawingContainer(view)
    lineDimensions = iDrawingContainer.Objects(dimension_type)

    if isinstance(lineDimensions, tuple):
        for dimension in lineDimensions:
            drawingObject = kompas_api7_module.IDrawingObject(dimension)
            drawingObject1 = kompas_api7_module.IDrawingObject1(drawingObject)

            if bool(drawingObject1.Constraints):
                continue
            else:
                # chooseMng.Choose(dimension)
                result.append(dimension)
    return result


# рекурсивный поиск файлов в директории
def run_fast_scandir(dir, ext):  # dir: str, ext: list
    subfolders, files = [], []

    for f in os.scandir(dir):
        if f.is_dir():
            subfolders.append(f.path)
        if f.is_file():
            if os.path.splitext(f.name)[1].lower() in ext:
                files.append(f.path)

    for dir in list(subfolders):
        sf, f = run_fast_scandir(dir, ext)
        subfolders.extend(sf)
        files.extend(f)
    return subfolders, files


subfolders, file_list = run_fast_scandir(path, [".cdw"])
changed_files = []

for file in file_list:
    kompas_document = application.Documents.Open(file, True)

    if kompas_document:
        iDocument2D = kompas_object.ActiveDocument2D()
        iDocument = application.ActiveDocument
        iKompasDocument2D = kompas_api7_module.IKompasDocument2D(iDocument)
        iKompasDocument2D1 = kompas_api7_module.IKompasDocument2D1(iKompasDocument2D)

        viewsAndLayersManager = iKompasDocument2D.ViewsAndLayersManager
        views = viewsAndLayersManager.Views

        chooseMng = iKompasDocument2D1.ChooseManager

        i = 0

        # dimension_type - тип объекта для поиска, см. в DrawingObjectTypeEnum
        dimension_type = [kompas6_constants.ksDrLDimension, kompas6_constants.ksDrADimension,
                          kompas6_constants.ksDrDDimension,
                          kompas6_constants.ksDrRDimension, kompas6_constants.ksDrRBreakDimension,
                          kompas6_constants.ksDrBase,
                          kompas6_constants.ksDrWPointer, kompas6_constants.ksDrCut, kompas6_constants.ksDrLeader,
                          kompas6_constants.ksDrPosLeader,
                          kompas6_constants.ksDrBrandLeader, kompas6_constants.ksDrMarkerLeader,
                          kompas6_constants.ksDrTolerance, kompas6_constants.ksDrMacro,
                          kompas6_constants.ksDrLBreakDimension,
                          kompas6_constants.ksDrABreakDimension,
                          kompas6_constants.ksDrOrdinateDimension, kompas6_constants.ksDrArcDimension,
                          kompas6_constants.ksDrChangeLeader, kompas6_constants.ksDrRemoteElement,
                          kompas6_constants.ksDrMarkOnLeader,
                          kompas6_constants.ksDrMarkOnLine, kompas6_constants.ksDrMarkInsideForm]

        # флаг наличия изменений в документе
        is_modifyed = False

        while i < views.Count:
            view = views.View(i)

            # для всех типов объектов
            # Dimensions_selector(kompas6_constants.ksAllObj, view)

            # для объектов, заданных в dimension_type из DrawingObjectTypeEnum
            for condition in dimension_type:
                Dimensions_selector(condition, view)

            drawingObject = kompas_api7_module.IDrawingObject(view)

            if len(result) != 0:
                is_modifyed = True
                layers = view.Layers
                layer = layers.Add()
                layer.Name = "Непараметризованное"
                layer.Color = int("0000FF", 16)
                layer.Update()
               
                for item in result:
                    dr = kompas_api7_module.IDrawingObject(item)
                    dr.LayerNumber = layer.LayerNumber
                    dr.Update()

                #делаем системный слой текущим
                system_layer = layers.Layer(0)
                system_layer.Current = True
                system_layer.Update()

            result[:] = []

            i += 1

        if is_modifyed:
            iDocument2D.ksRebuildDocument()
            iKompasDocument = kompas_api7_module.IKompasDocument(iDocument)
            iKompasDocument.Save()
            iDocument2D.ksCloseDocument()
            changed_files.append(file)
        else:
            iDocument2D.ksCloseDocument()

# запись в txt измененных документов
with open("changed_files.txt", 'w') as f:
    for file in changed_files:
        f.write(file + '\n')
    f.close()

Архив со скриптами:
Скрипты проверка параметризации.7z

Kilia

Спасибо!
Добавил для пакетной проверки всплывающее окно для выборка папки:
Вместо
path = r"C:\Users\spect\Desktop\Пример"
Вставил
path = easygui.diropenbox()
Теперь при запуске макроса, спрашивает какую папку проверять.
Только нужно установить yasygui, что-то типа pipe install yasygui.

Вират Лакх

Продолжаем учить разработчиков писать программы :)

import pythoncom - теперь не нужен, остался от старого подключения к компасу.

Если это работает, то это ещё не значит, что оно правильно/оптимально:
kompas_api_object = kompas_object.ksGetApplication7() - это не IKompasAPIObject, а уже IApplication
application = kompas_api_object.Application - эта строка не нужна, т.к. здесь у IApplication получили IApplication
Лучше:
iApplication = KompasObject.ksGetApplication7() или Dispatch('Kompas.Application.7')

Про это я уже писал в качестве рекомендации. Так как размер - это один объект, поддерживающий несколько интерфейсов, то можно сразу получить нужный без промежуточных:
drawingObject1 = kompas_api7_module.IDrawingObject1(dimension)
вместо
drawingObject = kompas_api7_module.IDrawingObject(dimension)
drawingObject1 = kompas_api7_module.IDrawingObject1(drawingObject)