Пример использования функции UserGetPlacementAndEntity

Автор yarikv, 21.05.07, 14:41:25

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

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

yarikv

может кто поделиться примером кода по этой функции для выбора двух граней. на делфи

yarikv


yarikv

если на делфи нет примеров. может кто на других языках поможет!!!

yarikv

неужели никто не использовал эту функцию в работе?

olden

06.06.07, 18:51:51 #4 Последнее редактирование: 06.06.07, 18:54:56 от olden

yarikv

ЦитироватьПример написания функции обратной связи SELECTCALLBACKPROC можешь взять из SDK

что это за пример? какой из них?

yarikv

11.06.07, 10:08:55 #6 Последнее редактирование: 11.06.07, 10:25:24 от yarikv
теперь такой вопрос?

function SELECTCALLBACKPROC(iEntity: PIDispatch;
         iRequestInfo3D:ksRequestInfo3D):integer; stdcall; export;
var
iEntityCollection: ksEntityCollection;
iEntity1: ksEntity;
begin
iEntity1:=ksEntity(iEntity);
if iEntity1 = nil then Exit;
iEntityCollection:=ksEntityCollection(iRequestInfo3D.GetEntityCollection);
iEntityCollection.Add(iEntity1);
Result:=1
end;

function LibraryName: PChar; pascal;
begin
Result:='Функция UserGetPlacementAndEntity';
end;

procedure LibraryEntry(command: WORD); pascal;
var
iKompas: KompasObject;
iDoc3D: ksDocument3D;
iPart: ksPart;
iRequestInfo3D: ksRequestInfo3D;
begin
iKompas:=KompasObject(CreateKompasObject);
if iKompas = nil then Exit;

iDoc3D:=ksDocument3D(iKompas.ActiveDocument3D);
if iDoc3D = nil then Exit;

iPart:=ksPart(iDoc3D.GetPart(pTop_Part));

iRequestInfo3D:=ksRequestInfo3D(iDoc3D.GetRequestInfo(iPart));
if iRequestInfo3D = nil then Exit;

iRequestInfo3D.SetCallBack('SELECTCALLBACKPROC', hinstance, nil);
iRequestInfo3D.SetFilterCallBack('SELECTFILTERPROC', hinstance, nil);
iRequestInfo3D.prompt:='Укажите цилиндрическую грань';
iDoc3D.UserGetPlacementAndEntity(2);

iKompas:=nil
end;

вот такой код. когда запускаю библиотеку функция фильтрации работает, запускается процесс выбора объектов. но я могу указать больше чем 2 объекта. хотя указываю, что нужно выбрать 2. в чем дело? что сделано не так?

olden

Я попробывал и вот что получилось на vb6.

Public Sub selectObject()
 
        Dim iReqInfo3D As Kompas6API5.RequestInfo3D
        Set iReqInfo3D = iDoc3D.GetRequestInfo(iPart)
        If iReqInfo3D Is Nothing Then Exit Sub
        iReqInfo3D.prompt = "Выбрать начальную точку"
        iReqInfo3D.SetCallBack "USERCALLBACKPROC", 0, Me '
        iReqInfo3D.SetFilterCallBack "USERFILTERCALLBACKPROC", 0, Me '
        If iDoc3D.UserGetPlacementAndEntity(0) Then
        'сдесь будут выполняться действия после нажатия кнопки "Enter"
        End If
       
End Sub

'////////////////////////////////////////
'USERFILTERCALLBACKPROC
Public Function USERFILTERCALLBACKPROC(ksEntity As Kompas6API5.entity) As Boolean

Dim x As Double, y As Double, Z As Double

If ksEntity.IsIt(o3d_vertex) = True Then         ' если элемент вершина
  USERFILTERCALLBACKPROC = True
  Exit Function
End If

USERFILTERCALLBACKPROC = False
End Function

'USERCALLBACKPROC
Public Function USERCALLBACKPROC(entity As Kompas6API5.entity, Info As Kompas6API5.RequestInfo3D) As Integer
If entity Is Nothing Then Exit Function
If Info Is Nothing Then Exit Function

Set infoEntityColl = Info.GetEntityCollection

If infoEntityColl.GetCount = 0 Then ' если выбрана начальная точка
  q = infoEntityColl.Add(entity) ' тогда ее добавляем в коллекцию
  i = infoEntityColl.GetCount
  Info.prompt = "Укажите конечную точку" 'меняем строку подсказку
  iDoc3D.ChangeObjectInLibRequest
  USERCALLBACKPROC = 1 'подтверждаем что изменения произошли
  Exit Function
End If

If infoEntityColl.GetCount = 1 Then ' если выбрана конечная точка
  q = infoEntityColl.Add(entity) ' тогда ее добавляем в коллекцию
  i = infoEntityColl.GetCount
  Info.prompt = "Нажмите применить" 'меняем строку подсказки
  iDoc3D.ChangeObjectInLibRequest
  USERCALLBACKPROC = 1 'подтверждаем что изменения произошли
  Exit Function
End If

USERCALLBACKPROC = 0 'все точки выбраны и зменений ни каких не будет

End Function

Но загвоздка вот в чем. Если выделить две точки и потом снять выделение с одной из выделеных точек, то программа считает что выделины все равно две точки и больше выделять ничего не хочет. Как вот проверить на снятие выделения? Я незнаю.

yarikv

у меня вопросы:

ЦитироватьIf iDoc3D.UserGetPlacementAndEntity(0) Then
- почему 0? ведь

ЦитироватьВходной параметр: entityCount - максимальное количество объектов, которое может быть одновременно указано в процессе.


yarikv

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

function SELECTCALLBACKPROC(iEntity: ksEntity;
         iRequestInfo3D:ksRequestInfo3D):integer; stdcall; export;
var
iEntityCollection: ksEntityCollection;
iFaceDef: ksFaceDefinition;
begin
iEntityCollection:=ksEntityCollection(iRequestInfo3D.GetEntityCollection);
iFaceDef:=ksFaceDefinition(iEntity.GetDefinition);

if iEntity <> nil then
begin
if iFaceDef.IsCylinder then
begin
iEntityCollection.SetByIndex(iEntity, 0);
Result:=1;
end;
if iFaceDef.IsPlanar then
begin
iEntityCollection.SetByIndex(iEntity, 1);
Result:=1;
end;
end;
end;

если у кого есть более лучшее решение, пожалуйста поделитесь

yarikv

немного поработав с этой функцией появились следующие наблюдения:

1. iDoc3D.UserGetPlacementAndEntity(entityCount) - данная строка определяет количество элементов переменной iEntityCollection, используемой в колбек-функции, т.е. после определения этой переменной в колбек-функции

iEntityCollection:=ksEntityCollection(iRequestInfo3D.GetEntityCollection);

значение iEntityCollection.GetCount будет равно entityCount

2. в процессе работы функции, если необходимо переназначить элемент, то нужно просто нажать на соответствующем элементе и с него снимется выделение. при этом соответствующий элемент коллекции  iEntityCollection примет значение nil.

для выбора цилиндрического и плоского элемента колбек-функцию делал в следующем виде:

function SELECTCALLBACKPROC(iEntity: ksEntity;
         iRequestInfo3D:ksRequestInfo3D):integer; stdcall; export;
var
iEntityCollection: ksEntityCollection;
iFaceDef: ksFaceDefinition;
begin
iEntityCollection:=ksEntityCollection(iRequestInfo3D.GetEntityCollection);
iFaceDef:=ksFaceDefinition(iEntity.GetDefinition);

if iEntity <> nil then
begin
if iFaceDef.IsCylinder then iEntityCollection.SetByIndex(iEntity, 0);
if iFaceDef.IsPlanar then iEntityCollection.SetByIndex(iEntity, 1);
Result:=1;
end;
end;

для выбора двух цилиндрических элементов (фильтр в функции фильтрации) с возможностью их редактирования:

function SELECTCALLBACKPROC(iEntity: ksEntity;
         iRequestInfo3D:ksRequestInfo3D):integer; stdcall; export;
var
i: byte;
iEntityCollection: ksEntityCollection;
begin
iEntityCollection:=ksEntityCollection(iRequestInfo3D.GetEntityCollection);

if iEntity <> nil then
begin
if (iEntityCollection.GetByIndex(0) = nil) then i:=1;
if ((iEntityCollection.GetByIndex(0) <> nil) and (iEntityCollection.GetByIndex(1) = nil)) then i:=2;

if i <> 0 then
begin
iEntityCollection.SetByIndex(iEntity, (i-1));
Result:=1;
end;
end;

если у кого есть соображения на эту тему прошу откликнуться. самому тяжело разбираться.