Создание контура по штриховке

Автор Sprinter500, 12.02.15, 17:59:33

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

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

Функция должна вернуть координаты куда то, вот она и возвращает их в XY.
+ Благодарностей: 1

Sprinter500

Понятно это как с функцией перевода строки в число:
var
z: integer;
begin
  val(Form1.eee.Text,aaa,z);
end

где z - код ошибки если функция не сработает. То есть передача идет во внешнюю переменную.

Ну я не ошибся - именно этой функцией ksGetCursorPosition надо определять координаты? А момент щелчка по рабочему полю Компаса ловим по коду клавиши в DirectX? Или я слишком усложнил процесс?

Функция ksGetCursorPosition возвращает координаты в переменные X и Y, плюс результат своей работы.
+ Благодарностей: 1

Sprinter500

Спасибо, уже многое начало проясняться. Завтра буду кодить, посмотрим что получится - может еще подводные камни повылазят.

Ну и малый пустячок неясным остался - как получить событие щелчка мыши не по своему окну? То есть программа должна отловить момент когда курсор находится именно над нужным местом поля чертежа.

В Компасе ksDocumentFrameNotifyEnum - подписка на события для окна документа: клавиатура, мышь, события по отрисовке документа, событие - MouseMove, но тут столько подводных камней, что я думаю Вы не разберётесь, раз Вы не разобрались с SAFEARRAY.
Можно через ловушку SetWindowsHookEx, но это уже WinApi и Вам уже на специализированный форум, т.к. к Компасу отношения не имеет.
+ Благодарностей: 1

Sprinter500

Спасибо большое! Ну хотя бы попробую разобраться. Если нет то найду другой путь.
Ну а с SAFERARRAY - вот было бы несколько разных примеров применения именно под Компас, а то есть всего один скрин с ветки куда Вы ссылку кидали - и все. Полной картины не дает. Тогда думаю бы разобрался.

Сегодня вечером попробую что-нибудь "слепить".

SAFERARRAY - смотрите пример Step3_API7_2D.
+ Благодарностей: 1

Sprinter500

Спасибо. Вроде понял логику работы safearray. Теперь буду пробовать переписать кода ранее написанных программ с использованием safarray.

Кстати о массивах :) , Sabahs, немного не по теме - Библиотеку "Сервисные инструменты"  Вы курируете? Там при массовой заменене текста в элементах чертежа командой "Замена текста" после выполнения - иногда вылазит сообщение "Неверный указатель массива". Примерно в 70% случаев. Что и почему пока не разобрался - логика появления сообщения не ясна.. Как бы ничего страшного - все работает корректно, но малость наприягает. V15.2 x64 (лицензия). Это косяки в чертежах или что?

#28
К библиотеке "Сервисные инструменты" я никакого отношения не имею - это разработка АСКОН.
Хотите получить ответ, пишете в СТП.

Sprinter500

Ясно. Просто раз там есть преобразование заливок и штриховок - а это появилось у Вас в "библиотете нахождения объектов" - я и прешил что это продложение БНО. Ну видимо ошибся извините. В СТП - уже писал по поводу другого серъезного косяка самого Компаса. А это мелочь.

Sprinter500

Sabahs, вот что у меня получилось. Пока сделал просто перебор всех штриховок, завтра сделаю как вариант для выделенных и для заливок. Посмотри пожалуйста  - может есть лишние элементы кода, может упростить можно, чтобы быстрее работало. А то перебор заметен глазу - не мгновенен.

var
  drawCont      : IDrawingContainer;
  arr           : OleVariant;
  pObj          : IDispatch;
  arrCount, j,
  objType       : integer;
  pDrawObj      : IDrawingObject;
  objRef        : reference;

begin
     // Получить контейнер графических объектов
   drawCont := GetDrawingContainer;
   if ( drawCont <> nil ) then
   begin
      // Тип 0 - все объекты
      //_variant_t objType = (long)0;
      // Получить массив SafeArray объектов
      arr := drawCont.Objects[13117];
      // Если массив есть и он не пуст
      if ( VarType(arr) = (VT_ARRAY Or VT_DISPATCH) ) then
      begin
         // Определить количество элементов
         arrCount := ( VarArrayHighBound( arr,  1 ) + 1 );
         for j := 0 to arrCount - 1 do
         begin
            // Получить элемент из массива
            pObj := arr[j];
            if ( pObj <> nil ) then
            begin
               // Получить интерфейс графического объекта
               pDrawObj := pObj As IDrawingObject;
               if ( pDrawObj <> nil ) then
               begin
                  // Получить тип объекта
                  objType := pDrawObj.DrawingObjectType;
                  // Получить референс объекта
                  objRef := pDrawObj.Reference;
            Document2D.ksStoreTmpGroup(Document2D.ksDuplicateBoundaries(objRef));
          end;
        end;
      end;
    end;
  end;

Тут не перебор, а дублирование границ без разбора есть они или нет, каждая ksStoreTmpGroup - это перерисовка  окна, отсюда и тормоза.
+ Благодарностей: 1

Sprinter500

Еще 2 маленьких вопросика.
Как сделать чтобы в массив одновременно передавались и заливки и штриховки
Вот тут: arr := drawCont.Objects[13117];
где 13117 - код штриховки, а 13119 - заливки.

И еще что нужно сделать чтобы вместо кода константу можно было вставлять? Например ksHatch. Какой то модуль подключить?

#33

1. arr := drawCont.Objects[0];...
objType := pDrawObj.DrawingObjectType;
Затем по objType выбираете только заливки и штриховки.


2. Не ksHatch, а ksDrHatch. Для этого нужно изучать SDK, чтобы выяснить, что описание находится ksConstTLB.pas.

+ Благодарностей: 1

Sprinter500

1. Но ведь тогда в цикле for j := 0 to arrCount - 1 do    увеличится параметр arrCount что приведет к перебору им всех объектов. Наверно торомзить сильнее начнет.

2. Это я по памяти не глядя. Каюсь :) Странно с кодом (ksObjectHatch 13117 Штриховка) все работает.  ksDrHatch соответствует коду 7. Вот ksObjectHatch и подчеркивался крансым, хотя ksConstTLB.pas был подключен. Надо попробовать еще ksDrHatch - но это уже вечером.

1. Зависит от Вас, как сделаете.
2. У IDrawingObject есть свои типы.
+ Благодарностей: 1

Sprinter500

Немного модернизировал код, для работы только с выделенными штриховками или заливками. Только вот почему то работает только если выделено более одного объекта. Не могу понять в чем причина.

procedure BackToContur();//Получение контура из штриховки или заливки
var
  drawCont      : IDrawingContainer;
  arr           : OleVariant;
  pObj          : IDispatch;
  arrCount, j,
  objType       : integer;
  pDrawObj      : IDrawingObject;
  objRef        : reference;
begin
  pKompasDocument2D1 :=  pKompasDocument2D as iKompasDocument2D1;
  pSelectionManager := pKompasDocument2D1.SelectionManager;
   drawCont := GetDrawingContainer;// Получить контейнер графических объектов
   if ( drawCont <> nil ) then
   begin
    arr := pSelectionManager.SelectedObjects; //Получить массив выделенных объектов
      if ( VarType(arr) = (VT_ARRAY Or VT_DISPATCH) ) then // Если массив есть и он не пуст
      begin
         arrCount := ( VarArrayHighBound( arr,  1 ) + 1 ); // Определить количество элементов
      ShowMessage(inttostr(arrCount));
      for j := 0 to arrCount - 1  do
      begin
        pObj := arr[j]; // Получить элемент из массива
        if ( pObj <> nil ) then
        begin
          pDrawObj := pObj As IDrawingObject; // Получить интерфейс графического объекта
          if ( pDrawObj <> nil ) then
          begin
            objType := pDrawObj.DrawingObjectType; // Получить тип объекта
            if (objType=ksDrHatch) or (objType=ksDrColorFill) then
            begin
              objRef := pDrawObj.Reference; // Получить референс объекта
              Document2D.ksStoreTmpGroup(Document2D.ksDuplicateBoundaries(objRef));
            end;
          end;
        end;
      end;
    end;
  end;
end;

Смотрите внимательно картинку которой было мало, чтобы разобраться с массивами.
+ Благодарностей: 1

Sprinter500

Спасибо помогло. Понял где собака зарыта ))))

А как ksCalcInertiaProperties в этот код прикрутить?