• Добро пожаловать на Форум пользователей ПО АСКОН. Пожалуйста, авторизуйтесь.
 

Уважаемые пользователи,

Хотим проинформировать вас о режиме работы регистрации на нашем сайте.

Зарегистрироваться возможно в рабочие дни, с 8:00 до 20:00 (мск).

Если у вас возникнут вопросы или потребуется дополнительная информация, не стесняйтесь обращаться к нашей службе поддержки. Вы можете связаться с нами по указанным контактным данным на нашем сайте.

Благодарим вас за понимание и сотрудничество. Мы ценим ваше терпение и стремимся предоставить вам лучший опыт использования нашего сервиса.

С уважением,
Команда Ascon

Грань или поверхность

Автор DUXOTA, 31.03.24, 00:44:39

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

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

DUXOTA

Имеется деталь, состоящая из нескольких раздельных кусочков
Как заставить программу тыкнуть в определённые координаты, чтобы достать нужную грань
все координаты известны
только непонятно как сделать выбор
Может есть другой способ как выделить данную грань, чтобы сделать вырез по ней?
Нужная поверхность выделена зелёным, оные удалить именно вырезом(простой пример для наглядности)
Код свой(который не работает) прикладываю ниже как и картинку
def select_faces_by_point(x, y, z):
    kompas = Dispatch("KOMPAS.Application.5")
    kompas.Visible = True  # Делаем окно КОМПАС-3D видимым

    try:
        # Получаем активный документ 3D
        doc3D = kompas.ActiveDocument3D()
        if doc3D is None:
            raise Exception("Не удалось получить активный документ 3D.")

        # Получаем коллекцию всех граней в детали
        entities = doc3D.EntityCollection(Obj3dType.o3d_face)

        # Выделяем грани, проходящие через заданную точку
        entities.SelectByPoint(x, y, z)

        # Сообщение об успешном выделении
        print("Грани, проходящие через точку ({}, {}, {}), успешно выделены.".format(x, y, z))

    except Exception as e:
        print("Произошла ошибка:", e)

# Задаем координаты точки для выделения граней
x_coord = 0
y_coord = 0
z_coord = 0

# Вызываем функцию для выделения граней по заданным координатам
select_faces_by_point(x_coord, y_coord, z_coord)

Вират Лакх

Вы уверены, что kompas = Dispatch("KOMPAS.Application.5") выдаёт правильный интерфейс? Для 5 такая запись не катит. Отсюда неправильная работа кода.

DUXOTA

Цитата: Вират Лакх от 31.03.24, 07:20:51Вы уверены, что kompas = Dispatch("KOMPAS.Application.5") выдаёт правильный интерфейс? Для 5 такая запись не катит. Отсюда неправильная работа кода.
Вообще не уверен, потому и получаю ошибку получения интерфейса
есть накидка по поводу данного кода:
collect = (ksEntityCollection)part.EntityCollection((short)Obj3dType.o3d_face)
но я не могу его никак реализовать, есть мысли у вас вообще?(или примеры может даже)

UU

Всё оно работает, только понять не могу, что вы на Питон так кинулись, есть нормальные языки программирования.

DUXOTA

Цитата: UU от 31.03.24, 21:04:01Всё оно работает, только понять не могу, что вы на Питон так кинулись, есть нормальные языки программирования.
Не понимаю как вы сделали это, подскажите пожалуйста(покажите пример желательно, можно на другом языке)
Я пишу на ассемблере, питоне, C#, делфи
впервые сталкиваюсь с компасом, потому пишу на открытом для детей коде питоне пока что
было бы круто если вы поспособствуете в решении моей проблемы

DUXOTA

Цитата: UU от 31.03.24, 21:04:01Всё оно работает, только понять не могу, что вы на Питон так кинулись, есть нормальные языки программирования.
и можете посоветовать языки для изучения, самые "хорошие" в вашем понимании, буду премного благодарен
Изучаю программирование для интереса

Вират Лакх

Попробуйте для начала подключение к компасу заменить на такое (это сильно упрощенный Dispatch):

from win32com.client import gencache
from pythoncom import connect

api5 = gencache.EnsureModule('{0422828C-F174-495E-AC5D-D31014DBBE87}', 0, 1, 0)
KompasObject = api5.KompasObject(connect('Kompas.Application.5'))

Это только подключение к запущенному компасу без создания в случае его отсутствия. Поэтому Visible = True не требуется.

DUXOTA

Цитата: Вират Лакх от 01.04.24, 06:01:24Попробуйте для начала подключение к компасу заменить на такое (это сильно упрощенный Dispatch):

from win32com.client import gencache
from pythoncom import connect

api5 = gencache.EnsureModule('{0422828C-F174-495E-AC5D-D31014DBBE87}', 0, 1, 0)
KompasObject = api5.KompasObject(connect('Kompas.Application.5'))

Это только подключение к запущенному компасу без создания в случае его отсутствия. Поэтому Visible = True не требуется.
Не сочтите за грубость, но если видно, я скинул функцию, отрывок, у меня есть уже огромные проекты и ваш ответ не отвечает на мой вопрос
Был бы благодарен, если все-таки ответили на вопрос, а не изобретались педали на велосипед с педалями, спасибо!
Это к слову про менталитете нашей страны, люди отвечают на то что хотят ответить, а не то что просят(отсылка к конституции)

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


kompas_document = application.ActiveDocument
kompas_document_3d = kompas_api7_module.IKompasDocument3D(kompas_document)
part7 = kompas_document_3d.TopPart
IModelObject = kompas_api7_module.IModelObject(part7)
a = IModelObject.Owner.ModelObjects(0)
print(part7.SelectByPoint(a, 60, 10, 20))
Вот решение вашей задачи
p.s Координаты выберите другие какие вам нужны
+ Благодарностей: 1

Вират Лакх

Цитата: DUXOTA от 01.04.24, 06:42:48Не сочтите за грубость, но если видно, я скинул функцию, отрывок, у меня есть уже огромные проекты и ваш ответ не отвечает на мой вопрос
Был бы благодарен, если все-таки ответили на вопрос, а не изобретались педали на велосипед с педалями, спасибо!
Это к слову про менталитете нашей страны, люди отвечают на то что хотят ответить, а не то что просят(отсылка к конституции)
Сочту за грубость.
Цитата: DUXOTA от 31.03.24, 00:44:39Код свой(который не работает) прикладываю
Что значит "не работает"? Конкретно пишите, что выдаёт. У меня Ваша писанина из огромных проектов пишет: 'ksDocument3D' object is not callable
А у Вас?
После её исправления EntityCollection нужно взять от "правильного" объекта. Как и в примере выше, я взял от верхнего компонента.
# Получаем коллекцию всех граней в детали
entities = doc3D.GetPart(-1).EntityCollection(6)
print(entities.GetCount())

# Выделяем грани, проходящие через заданную точку
print(entities.SelectByPoint(0, 0, 0))
print(entities.GetCount())

ksSelectionMng = doc3D.GetSelectionMng()
print(ksSelectionMng.Select(entities.First()))
+ Благодарностей: 1

DUXOTA

Цитата: Вират Лакх от 01.04.24, 12:58:15Сочту за грубость.Что значит "не работает"? Конкретно пишите, что выдаёт. У меня Ваша писанина из огромных проектов пишет: 'ksDocument3D' object is not callable
А у Вас?
После её исправления EntityCollection нужно взять от "правильного" объекта. Как и в примере выше, я взял от верхнего компонента.
# Получаем коллекцию всех граней в детали
entities = doc3D.GetPart(-1).EntityCollection(6)
print(entities.GetCount())

# Выделяем грани, проходящие через заданную точку
print(entities.SelectByPoint(0, 0, 0))
print(entities.GetCount())

ksSelectionMng = doc3D.GetSelectionMng()
print(ksSelectionMng.Select(entities.First()))
Я же сказал, это маленькая функция, что же вы так воспринимаете то все)
Проекты большие, по 5 тысяч строк
Но у всех бывают моменты затупка
Во всяком случае извините, если задел вас, возможно не так выразился

DUXOTA

Цитата: Chipchilinka_1 от 01.04.24, 08:41:31Вот решение вашей задачи
p.s Координаты выберите другие какие вам нужны
Выдаёт такую штуку
(<win32com.gen_py.69AC2981-37C0-4379-84FD-5DD2F3C0A520x0x1x0.IFace instance at 0x1935344338224>,)
как я понимаю, мы получаем кортеж поверхностей, а надо то только первую грань
играясь с кодом не пришёл к решению :(

Вират Лакх

Возьмите только первый элемент. Наверно ответ всегда является кортежем. Через API5 SelectByPoint фильтровал коллекцию.

DUXOTA

Цитата: Вират Лакх от 03.04.24, 04:44:14Возьмите только первый элемент. Наверно ответ всегда является кортежем. Через API5 SelectByPoint фильтровал коллекцию.
Я это и пытался сделать, но почему-то возникают ошибки с менеджером выборки
# -*- coding: utf-8 -*-
import pythoncom
from win32com.client import Dispatch, gencache

def select_faces_by_point(x, y, z):
    try:
        # Получаем объект приложения KOMPAS-3D
        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))

        # Получаем активный документ
        kompas_document = application.ActiveDocument

        # Получаем 3D-документ из активного документа
        doc3D = kompas_api7_module.IKompasDocument3D(kompas_document)

        # Получаем часть
        part7 = doc3D.TopPart

        # Выбираем грани, проходящие через заданную точку
        IModelObject = kompas_api7_module.IModelObject(part7)
        a = IModelObject.Owner.ModelObjects(0)
        selected_entities = part7.SelectByPoint(a, x, y, z)

        # Проверяем, есть ли выбранные сущности
        if selected_entities:
            print("Количество выбранных граней:", len(selected_entities))
            # Пытаемся выбрать первую грань из выбранных сущностей
            selected_face = selected_entities[0]
            print("Первая выбранная грань:", selected_face)

            # Возвращаем выбранную грань
            return selected_face
        else:
            print("Ничего не выбрано")
            return None
    except Exception as e:
        print("Произошла ошибка:", e)
        return None

# Задаем координаты точки для выделения граней
x_coord = 10
y_coord = 10
z_coord = 10

# Вызываем функцию для выделения граней по заданным координатам
selected_face = select_faces_by_point(x_coord, y_coord, z_coord)

# Если грань была выбрана, выберем её через SelectionMng
if selected_face:
    try:
        # Получаем объект ksSelectionMng
        ksSelectionMng = selected_face.GetSelectionMng()

        # Выбираем грань через ksSelectionMng
        ksSelectionMng.Select(selected_face)
    except Exception as e:
        print("Произошла ошибка при выборе грани через SelectionMng:", e)
Ошибка в данном случае связанная с получением его
>>>
Количество выбранных граней: 1
Первая выбранная грань: <win32com.gen_py.69AC2981-37C0-4379-84FD-5DD2F3C0A520x0x1x0.IFace instance at 0x53573072>
Произошла ошибка при выборе грани через SelectionMng: '<win32com.gen_py.69AC2981-37C0-4379-84FD-5DD2F3C0A520x0x1x0.IFace instance at 0x53573072>' object has no attribute 'GetSelectionMng'
>>>

Михаил88

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

def select_faces_by_point(x, y, z):
    try:
        # Получаем объект приложения KOMPAS-3D
        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))

        # Получаем активный документ
        kompas_document = application.ActiveDocument

        # Получаем 3D-документ из активного документа
        doc3D = kompas_api7_module.IKompasDocument3D(kompas_document)

        # Получаем часть
        part7 = doc3D.TopPart

        # Выбираем грани, проходящие через заданную точку
        IModelObject = kompas_api7_module.IModelObject(part7)
        a = IModelObject.Owner.ModelObjects(0)
        selected_entities = part7.SelectByPoint(a, x, y, z)

        # Проверяем, есть ли выбранные сущности
        if selected_entities:
            print("Количество выбранных граней:", len(selected_entities))
            # Пытаемся выбрать первую грань из выбранных сущностей
            selected_face = selected_entities[0]
            print("Первая выбранная грань:", selected_face)
            selection_manager = doc3D.SelectionManager
            selection_manager.Select(selected_face)

            # Возвращаем выбранную грань
            # return selected_face
        else:
            print("Ничего не выбрано")
            return None
    except Exception as e:
        print("Произошла ошибка:", e)
        return None

# Задаем координаты точки для выделения граней
x_coord = 10
y_coord = 10
z_coord = 10

# Вызываем функцию для выделения граней по заданным координатам
selected_face = select_faces_by_point(x_coord, y_coord, z_coord)

У Вас ошибки в коде. Теперь работает.

Цитата: DUXOTA от 03.04.24, 14:33:44# Получаем объект ksSelectionMng
ksSelectionMng = selected_face.GetSelectionMng()

Вот здесь ошибка Вы пытаетесь получить ksSelectionMng от IFace, а надо от ksDocument3D. Да и вообще не нужен здесь GetSelectionMng - это API5. Здесь нужно делать на API7.

selection_manager = doc3D.SelectionManager
selection_manager.Select(selected_face)
+ Благодарностей: 1

DUXOTA

Всем спасибо!
Тему считаю закрытой
С наступающей Пасхой!!! :w:  :w:  :w:

Warlock-72

Цитата: DUXOTA от 03.04.24, 18:23:05... С наступающей Пасхой!!!
Пасха через месяц только - 5 мая  8-)

DUXOTA

Цитата: Warlock-72 от 03.04.24, 18:27:59Пасха через месяц только - 5 мая  8-)
Приятности в натолоке тоже хочется, в виде наступающего празднества)))))))))))))))))