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

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

« предыдущая - следующая »

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

yarikv

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

yarikv

или пример написания callBack - функции?

yarikv

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

yarikv

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

olden

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

yarikv

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


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

yarikv

11.06.07, 09:08:55 #6 Последнее редактирование: 11.06.07, 09: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;

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