Временные сопряжения

Автор graphdark, 12.04.21, 08:29:58

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

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

graphdark

Не могу найти файл studs3d.rtw. Или намекните, как для фантома временные сопряжения создать соосности и совпадения. Вставку осуществляю так.
  begin
  part:=ksPart(doc3d.GetPart(pNew_Part));
  part.name:='Деталь'+Edit4.Text+'x'+Edit5.Text;
  part.fileName:=path;
  iRequestInfo3D := ksRequestInfo3D(Doc3D.GetRequestInfo(Part));
  iRequestInfo3D.prompt:='Укажите положение стандартного изделия';
  iRequestInfo3D.SetCallBack('SELECTCALLBACKPROC', hinstance, nil);
  iRequestInfo3D.CreatePhantom;
  ksPart(iRequestInfo3D.GetIPhantom).standardComponent:=true;
  Place:=ksPlacement(part.GetPlacement());
  if doc3d.UserGetPlacementAndEntity(0) then
     begin
     part.SetPlacement(iRequestInfo3D.GetPlacement());
     doc3d.SetPartFromFile(path,part,true);
     part.UpdatePlacement;
     part.Update;
     doc3d.RebuildDocument;
     end;

graphdark

Огромное спасибо всем, кто помог. Решение, может и не совсем верное кроется в 4х строчках кода. Studs3D это пример для С++, но он малоинформативен. Мне надо было при вставке стандартного назначить ему 2 сопряжения: соосность и совпадение. Делается это так:
var
part, phantom: kspart; // вся фишка в переменной фантом.
EntityConcentric, EntityConcidence, EntityConcentric2, EntityConcidence2: ksEntity;
EntityCollection: ksEntityCollection;
...
Обязательно нужна функция:
function  SELECTFILTERPROC(iEntity: ksEntity): Boolean; stdcall; export;
var iFaceDef: ksFaceDefinition;
begin
iFaceDef:=ksFaceDefinition(iEntity.GetDefinition);
Result:=(iEntity.type_ = o3d_face) and (iFaceDef.IsCylinder or iFaceDef.IsPlanar)
end;

Функцию пропишите в Exports. Даже если у вас VCL приложение. Все. Теперь берем первые объекты сопряжений, сразу после его создания:
  phantom:=ksPart(iRequestInfo3D.GetIPhantom);
  EntityCollection:=ksEntityCollection(Part.EntityCollection(o3d_face));
  EntityConcentric:=ksEntity(phantom.GetDefaultEntity(o3d_axisOZ));
  EntityConcidence:=ksEntity(phantom.GetDefaultEntity(o3d_planeXOY));

Для вторых объектов я делал сообщения.
  strPromt:='Укажите отверстие';
  strPromt1:='Укажите плоскость совпадения';
  EntityConcentric2:=ksEntity(Doc3D.UserSelectEntity(nil,
                      'SELECTFILTERPROC', strPromt, hinstance, nil));
  EntityConcidence2:=ksEntity(Doc3D.UserSelectEntity(nil,
                      'SELECTFILTERPROC', strPromt1, hinstance, nil));


И последнее. Сами сопряжения. Код полностью, с куском от вставки:
  if Doc3D.UserGetPlacementAndEntity(2) then
    begin
    Part.SetPlacement(iRequestInfo3D.GetPlacement);
    Doc3D.SetPartFromFile(path+FileName, Part, true);
    Doc3d.AddMateConstraint(mc_Concentric, EntityConcentric, EntityConcentric2, 0,0,0);
    Doc3d.AddMateConstraint(0, EntityConcidence,EntityConcidence2, 0,0,0);
    Part.UpdatePlacement;
    end;
Почему 0, а не mc_Concidence. Потому что ide ругается на mc_Concidence. Видимо Луна не в Сатурне. Блин. недели 2 бился. Спасибо форуму.

Михаил88

Цитата: graphdark от 04.05.21, 10:09:51function  SELECTFILTERPROC(iEntity: ksEntity): Boolean; stdcall; export;
var iFaceDef: ksFaceDefinition;
begin
iFaceDef:=ksFaceDefinition(iEntity.GetDefinition);
Result:=(iEntity.type_ = o3d_face) and (iFaceDef.IsCylinder or iFaceDef.IsPlanar)
end;

graphdark, если объект не подходит, функция возвращает False. У вас объект подсвечивается или нет?

graphdark

Цитата: Михаил88 от 06.07.21, 09:11:05graphdark, если объект не подходит, функция возвращает False. У вас объект подсвечивается или нет?
Нет он просто не выбирается.

graphdark

Цитата: Михаил88 от 06.07.21, 09:11:05graphdark, если объект не подходит, функция возвращает False. У вас объект подсвечивается или нет?
Прошу прощения. Счас проверил. И правда подсвечивает.

Михаил88

#5
Вот и у меня подсвечивается. А по идее не должно, чтобы у пользователя не было возможности для выбора объектов, которые не подходят по условию. Я пишу на питоне. Думал, что у меня только они подсвечиваются. Если посмотреть на библиотеку стандартные изделия то там, когда выбираешь объекты для сопряжения четко видно, что объекты которые не подходят по условию не подсвечиваются и их не возможно выбрать и передать процессу.

graphdark

Я вот пока не придумал, как двойной клик обработать, по вставленному элементу. Ну и подсказки при вставке, как из библиотеки были бы весьма не лишними. А про подсвечивание я даже и не заметил, пока вы не сказали.

Михаил88

graphdark, если охота, чтобы детали в сборку вставлялись аналогично тому, как из библиотеки стандартных изделий, нужно делать наложение сопряжений по другому.
SetFilterCallBackEx - Установить функцию обратной связи для фильтрации объектов
SELECTFILTERPROC (LPDISPATCH _entity) - прописываем по какому принципу будут фильтроваться объекты (объекты удовлетворяющие условию будут подсвечиваться при наведении на них курсора)

SetCallBackEx Установить функцию обратной связи.
SELECTCALLBACKPROC(LPDISPATCH entity, LPDISPATCH info) - выбираем объект и накладываем на него временные сопряжения (интерфейс ksMateConstraint) через свойства этого интерфейса назначаем тип сопряжения, направление и т.д. Через метод SetBaseObj - Установить указатель на интерфейс объекта для сопряжения по номеру
делается для двух объектов. Далее выполняем метод Create(). И заносим сопряжение в коллекцию сопряжений метод AddMateConstraint.

После того, как деталь появилась в сборке (iDocument3D.SetPartFromFileEx(FileName, iPart, True, True))
нужно установить постоянные сопряжения используя метод AddMateConstraint. EntityConcidence2 и EntityConcentric2 (объекты, которые мы выбрали) получаем из коллекции ksEntityCollection.

Далее перестраиваем и обновляем активное окно
iDocument3D.RebuildDocument()
kompas_object.ksRefreshActiveWindow()

В SDK довольно таки неплохо все описано(нужно читать внимательно). Плюсом можно посмотреть пример в studs3d.

graphdark


Михаил88


Михаил88

Но у меня на питоне будет

graphdark

Цитата: Михаил88 от 08.07.21, 16:33:03Но у меня на питоне будет
Да пофиг. Читаю и понимаю без словаря.)) Да и заметили уже, наверняка, что синтаксисы похожи.

Михаил88

    def CallBackP(self, iEntity, ksRequestInfo3D):
        iDocument3D = api.ActiveDocument3D()
        ksRequestInfo3D = Dispatch(ksRequestInfo3D)
        # Создать фантом
        ksRequestInfo3D.CreatePhantom()
        # Получить указатель на интерфейс фантома (указатель на интерфейс ksPart)
        phantom = ksRequestInfo3D.GetIPhantom()
        ksEntity = Dispatch(iEntity)
        ksFaceDef = ksEntity.GetDefinition()

        ksEntityCollection = ksRequestInfo3D.GetEntityCollection()
        print(ksEntityCollection)

        ksRequestInfo3D.prompt = "Укажите цилиндрическую поверхность"
        ksMateConstraintCollection = ksRequestInfo3D.GetMateConstraintCollection()

        if ksEntity.type == 6 and ksFaceDef.IsPlanar():# Если выбрана плоскость
            ksEntityCollection.Add(ksEntity)

            EntityConcidence = phantom.GetDefaultEntity(1)
            EntityConcidence2 = ksEntity
            ksMateConstraint = iDocument3D.GetMateConstraint()
            ksMateConstraint.constraintType = 0 #mc_Coincidence
            ksMateConstraint.direction = 0 #не учитывать направление
            ksMateConstraint.fixed = 0
            ksMateConstraint.SetBaseObj(1, EntityConcidence)
            ksMateConstraint.SetBaseObj(2, EntityConcidence2)
            print(ksMateConstraint.Create())
            print(ksMateConstraintCollection.AddMateConstraint(ksMateConstraint))

            return 1

        elif ksEntity.type == 6 and ksFaceDef.IsCylinder():# Если выбрана цилиндрическая плоскость
            ksEntityCollection.Add(ksEntity)

            EntityConcentric = phantom.GetDefaultEntity(73)
            EntityConcentric2 = ksEntity
            ksMateConstraint = iDocument3D.GetMateConstraint()
            ksMateConstraint.constraintType = 4  # mc_Concentric
            ksMateConstraint.direction = 0  # не учитывать направление
            ksMateConstraint.fixed = 0
            ksMateConstraint.SetBaseObj(1, EntityConcentric)
            ksMateConstraint.SetBaseObj(2, EntityConcentric2)
            print(ksMateConstraint.Create())
            print(ksMateConstraintCollection.AddMateConstraint(ksMateConstraint))
            return 1

        else:
            return 0

    def CallBackF(self, iEntity):
        ksEntity = Dispatch(iEntity)
        ksFaceDef = ksEntity.GetDefinition()
        if ksEntity.type == 6 and (ksFaceDef.IsCylinder() or ksFaceDef.IsPlanar()):
            return True
        else:
            return False

Михаил88

    iDocument3D = kompas_object.ActiveDocument3D()
    iPart = iDocument3D.GetPart(-3)
    iPart.fileName = FileName
    ksRequestInfo3D = iDocument3D.GetRequestInfo(iPart)
    ocx = Dispatch("Python.DispatchOCX")
    ksRequestInfo3D.prompt = "Укажите плоскость"
    ksRequestInfo3D.SetFilterCallBackEx(u'CallBackF', 0, ocx)
    ksRequestInfo3D.SetCallBackEx(u'CallBackP', 0, ocx)
    # Создать фантом
    ksRequestInfo3D.CreatePhantom()
    # Получить указатель на интерфейс фантома
    ksPart = ksRequestInfo3D.GetIPhantom()
    try:
        # Получить указатель на интерфейс параметров цвета и визуальных свойств компонента
        iColorParam = ksPart.ColorParam()
    except AttributeError:
        return
    # useColor - Используемый цвет (цвет источника, цвет хозяина, собственный цвет)
    iColorParam.useColor = 0
    # transparency - Прозрачность
    iColorParam.transparency = 0.5
    ksPart.Update()
    if iDocument3D.UserGetPlacementAndEntity(2):
        ksEntityCollection = ksRequestInfo3D.GetEntityCollection()
        EntityConcidence = ksPart.GetDefaultEntity(1)
        EntityConcentric = ksPart.GetDefaultEntity(73)
        iDocument3D.SetPartFromFileEx(FileName, iPart, True, True)
        iDocument3D.AddMateConstraint(0, EntityConcidence, ksEntityCollection.GetByIndex(2), 0, 0, 0)
        print((ksEntityCollection.GetByIndex(2)).type)
        iDocument3D.AddMateConstraint(4, EntityConcentric, ksEntityCollection.GetByIndex(3), 0, 0, 0)
        iColorParam.useColor = 2
        ksPart.Update()
        iDocument3D.RebuildDocument()
        kompas_object.ksRefreshActiveWindow()
        return

Михаил88

IModelLibrary = kompas_object.GetModelLibrary()
FileName = IModelLibrary.ChoiceModelFromLib('C:\Program Files\ASCON\KOMPAS-3D v18\Libs\Библиотека.kle', 0)[0]

Этот код запускает окно выбора детали из библиотеки kle.
Screenshot_1.png


потом эта переменная FileName(путь вставляемой детали) применяется здесь
iDocument3D.SetPartFromFileEx(FileName, iPart, True, True)
+ Благодарностей: 1

Михаил88

код еще нужно будет немного доработать (сделать проверки и протестировать). Но уже это все дает результат.

graphdark

Спасибо. Буду переводить.

midreyk

#17
Прошу помочь в написании кода на питоне.
Взял код из вышестоящего примера Михаил88. Но почему, то не работает. Запускается процесс выбора, но никакие объекты не выбираются и сопряжения не накладываются. При нажатии кнопки создания, деталь вставляется по координатам курсора без сопряжений.
Что не так и как это всё работает? Такое ощущение, что функции CallBack вообще не запускаются.

Распаковывать в корень диска D или поменять путь к детали в программе.
Питон 3.2, Компас 18