Модификация узлов дерева сборки

Программирование для CATIA.

Модификация узлов дерева сборки

Сообщение VladimirK » 26 май 2016 10:01

Здравствуйте!
Появилась необходимость изменить графические свойства узлов дерева сборки (графа).
В документации CAA RADE есть пример "Document / The Object Navigator".
Там показано как можно создать дерево объектов и изменить графические свойства узлов (иконка, цвет).
Для изменения графического представления в примере создаётся компонент, унаследованный от класса-адаптера CATNodeExtension и реализующий интерфейс CATINavigModify:
Код: Выделить всё
#include "TIE_CATINavigModify.h"
TIE_CATINavigModify(CAAOmbNavigModifyRoot);
CATImplementClass(CAAOmbNavigModifyRoot, DataExtension, CATBaseUnknown, CAASysGeomRootObj_node);

Только главное, что этот класс реализует интерфейс CATINavigModify для созданного в примере ранее объекта CAASysGeomRootObj_node.

Скажите, пожалуйста, как можно создать такой же компонент, только реализующий интерфейс CATINavigModify для стандартных объектов CATIA - узлов дерева сборки. Я пробовал по аналогии написать класс CAATreeNodeExtension:
Код: Выделить всё
CAATreeNodeExtension.h:

class CAATreeNodeExtension: public CATNodeExtension
{
   CATDeclareClass;
public:
   CAATreeNodeExtension();
   virtual ~CAATreeNodeExtension();
   // Реализация метода интерфейса CATINavigModify::UpdateElem
   // Определяет графическое представление узла (node)
   void UpdateElem (CATNavigInstance *iInstance);
};

CAATreeNodeExtension.cpp:

#include "TIE_CATINavigModify.h"
TIE_CATINavigModify(CAATreeNodeExtension);

CATImplementClass(CAATreeNodeExtension, DataExtension, CATBaseUnknown, ASMPRODUCT_node);

// Дополнительно, в файле словаря CAATreeAccessFW.dico:
// ASMPRODUCT_node   CATINavigModify   libCAATreeAccessAddIn

CAATreeNodeExtension::CAATreeNodeExtension(): CATNodeExtension()
{
}

CAATreeNodeExtension::~CAATreeNodeExtension()
{
}

void CAATreeNodeExtension::UpdateElem(CATNavigInstance *iInstance)
{
   CATIGraphNode *piGraphNode = NULL;
   HRESULT rc = QueryInterface(IID_CATIGraphNode, (void**)&piGraphNode);
   if (SUCCEEDED(rc))
   {
      piGraphNode->SetColor(50);
      piGraphNode->SetPixelImage("CustomIcon");
      piGraphNode->Release();
      piGraphNode = NULL;
   }
}

Здесь ASMPRODUCT_node - это имя класса узла сборки. Этот класс стандартный, я его не создавал, а нашёл имя с помощью утилиты "CAAV5 Object Browser".
Однако класс-компонент не загружается.

Скажите, пожалуйста, может быть нужно указать вместо класса ASMPRODUCT_node другой.
И вообще, можно ли это реализовать не для своего класса, как в примере, а для стандартного, уже существующего (в моём случае, узел дерева сборки).
Как я понял из документации CAA RADE, есть классы-адаптеры и они для этого и предназначены.
Можно создать свой компонент, наследовать его от класса-адаптера и реализовать нужные методы интерфейсов.
Или это не так? Буду рад вашей помощи, спасибо!
VladimirK
Новичок
Новичок
 
Сообщения: 63
Зарегистрирован: 15 ноя 2011 21:44

Re: Модификация узлов дерева сборки

Сообщение Wireless_Fidelity » 26 май 2016 14:22

Здравствуйте.

CATImplementClass изначально предназначен для добавления поведения уже существующим компонентам. Поэтому должно быть возможным создать класс-расширение, реализующее CATINavigModify, и при этом указать в качестве расширяемого компонента (последний аргумент) ASMPRODUCT_node. После чего в файле dico указать, что реализация CATINavigModify для этого компонента берется из Вашей dll.

Вопрос интересный, поэтому, пожалуйста, держите в курсе Вашего прогресса.
Аватара пользователя
Wireless_Fidelity
Активный участник
Активный участник
 
Сообщения: 394
Зарегистрирован: 10 апр 2010 00:11

Re: Модификация узлов дерева сборки

Сообщение Wireless_Fidelity » 26 май 2016 14:35

Также нашел пример изменения иконки в CAAPstProductIcon.
Там используется комбинация двух компонентов:
- реализация CATInit
- реализация же CATICustoIconProduct
Но при этом используется специальный документ, в котором уже есть компонент расширения CAAPstProductIconExt... Не очень понятно, как он там оказался, и как этот компонент разместить в обычном документе CATProduct.
Аватара пользователя
Wireless_Fidelity
Активный участник
Активный участник
 
Сообщения: 394
Зарегистрирован: 10 апр 2010 00:11

Re: Модификация узлов дерева сборки

Сообщение VladimirK » 27 май 2016 10:51

Здравствуйте.
Wireless_Fidelity, спасибо Вам за ответ!
Насчёт макроса CATImplementClass я так же понял, т.е. он объявляет, что создаваемый класс является расширением уже существующего.
В своём классе указал: CATImplementClass(CAATreeNodeExtension, DataExtension, CATBaseUnknown, ASMPRODUCT_node);
В словаре *.dico тоже: ASMPRODUCT_node CATINavigModify libCAATreeAccessAddIn
Но CATIA не загружает созданный компонент.
Всё-таки я до конца не понимаю механизм расширения существующих компонентов своими.
Получается, что я создал компонент, указал в файле словаря:
ASMPRODUCT_node CATINavigModify libCAATreeAccessAddIn
Но в стандартном файле словаря ..\code\dictionary\ProductStructure.dic тоже есть запись:
ASMPRODUCT_node CATINavigModify libCATProductStructure1
Т.е. получается, что реализация интерфейса CATINavigModify для ASMPRODUCT_node находится сразу в двух библиотеках: стандартной ..\code\bin\CATProductStructure1.dll и моей CAATreeAccessAddIn.dll.
Возможно ли это не знаю. И может это можно как-то обойти с помощью механизма наследования в C++, например наследовать интерфейсы...

Второй вариант, как в примере "Customizing Product's Icons" тоже не получился.
Но думаю этот вариант не совсем подходит для задачи. Расширение CAAPstProductIconExt реализует интерфейс CATICustoIconProduct для изменения иконки.
И активация этого расширения выполняется в методе Init, с помощью реализации интерфейса CATInit у объекта CAAPstProductIconCont.
Этот объект CAAPstProductIconCont для примера внедрён в сборку. Поэтому, в итоге и меняются иконки, из-за того, что в контейнер сборки внедрили дополнительно CAAPstProductIconCont.

Пока только удалость изменить иконку у CATIProduct, просто получив у него CATIGraphNode, и выполнив pGraphNode->SetPixelImage("CustomIcon").
Но это действие приходится выполнять "самому", т.е. из команды Add-In'a.
А чтобы "сама" CATIA изменяла иконку, с помощью компонента, реализующего CATINavigModify для ASMPRODUCT_node, пока никак не получается сделать.
VladimirK
Новичок
Новичок
 
Сообщения: 63
Зарегистрирован: 15 ноя 2011 21:44

Re: Модификация узлов дерева сборки

Сообщение Wireless_Fidelity » 27 май 2016 20:06

Если в двух dico указаны две разные реализации одного интерфейса, то будет использована одна из них. Обычно CATIA использует первый загруженный файл. Попрлбуйте поэкспкриментировать с порядком папок в переменной окружения CATDictionary (не помню точное имя).

Что касается юзкейса CAAPstProductIcon, то, как мне кажется, там используется feature extension. Увы, механизм не такой тривиальный, как обычное расширение через code extension или data extension.
1. С помощью утилиты CATFctEditorAssistant создается файл каталога CATFct и файл с описанием расширений фич - osm
2. В файле osm добавляется описание расширения фичи Product с описанием типа и имени контейнера (applicative container), в котором это расширение создается.
3. Каталог обновляется из файла osm с помощью той же утилиты, кладется в нужную папку, указанную в файле окружения.
4. Программист создает компонент контейнера с именем, которое было указано в osm, реализуя интерфейс CATInit
5. Программист создает компонент рвсширения фичи с именем из osm, реализуя CATINavigModify (или другой нужный интерфейс)
6. При загрузке CATIA объявленные контейнеры для расширений фич будут АВТОМАТИЧЕСКИ созданы инфраструктурой. При это вызовется реализация CAtInit, в которой следует активировать расширения через CATFmFeatureFacade

Увы, это лишь теория, но, как по мне, звучит разумно.
P.S. Извиняюсь за опечатки и неточности в описании имен, пишу по памяти и с телефона.
Аватара пользователя
Wireless_Fidelity
Активный участник
Активный участник
 
Сообщения: 394
Зарегистрирован: 10 апр 2010 00:11

Re: Модификация узлов дерева сборки

Сообщение VladimirK » 31 май 2016 14:53

Здравствуйте,
Wireless_Fidelity, спасибо за подробное объяснение по примеру CAAPstProductIcon.
Все эти дни я пытался написать компонент DataExtension, наследующий CATNodeExtension и реализующий CATINavigModify для ASMPRODUCT_node.
Вместо ASMPRODUCT_node пробовал и другие классы - ASMPRODUCTPPR_node, CATGRNode.
Следуя Вашему совету, экспериментировал с последовательностью путей в переменной окружения CATDictionaryPath.
Также пробовал вообще временно убрать из стандартного словаря ProductStructure.dic строку "ASMPRODUCT_node CATINavigModify libCATProductStructure1", для загрузки моего класса с реализацией. Всё безуспешно.

Единственное, что получилось - это изменить иконку у CATIProduct из команды Add-In'a, напрямую, через интерфейс CATIGraphNode.
Для этого получил через цепочку CATFrmLayout->CATFrmWindow->CATFrmNavigGraphicWindow->CATNavigBox->CATNavigController для CATIProduct ассоциированный с ним узел в дереве методом CATNavigController::GetAssociatedElements(), привёл его к типу CATIGraphNode и задал иконку методом CATIGraphNode::SetPixelImage("CustomIcon").

Теперь проблема заключается в том, что после раскрытия узла сборки в дереве (+) иконка опять становится стандартной.
Думаю, что эту проблему можно решить, обрабатывая события раскрытия узла дерева или события перерисовки.
В интерфейсе CATIRedrawEvent нашёл метод GetRedrawNotification() и пытался обработать события, тоже безуспешно.
Пробовал для узла CATIGraphNode создавать Callback с помощью глобальной функции ::AddCallback():
Код: Выделить всё
CATIRedrawEvent *piRedrawEvent = NULL;               
if (SUCCEEDED(pGraphNode->QueryInterface(IID_CATIRedrawEvent, (void**)&piRedrawEvent)))
{
   CATBaseUnknown *pUnk = NULL;
   if (SUCCEEDED(pGraphNode->QueryInterface(IID_CATBaseUnknown, (void**)&pUnk)))
   {
      CATCallback redrawCB = ::AddCallback(this, pUnk, piRedrawEvent->GetRedrawNotification(), (CATSubscriberMethod)&MyCmdClass::RedrawEventCB);
      pUnk->Release();
      pUnk = NULL;
   }
   piRedrawEvent->Release();
   piRedrawEvent = NULL;
}

piRedrawEvent->GetRedrawNotification() возвращает значение, CATCallback redrawCB тоже получает значение, но метод-обработчик RedrawEventCB не вызывается...
Подскажите, пожалуйста, как всё-таки можно отследить события раскрытия узлов дерева или перерисовки, чтобы после этого опять перерисовывать иконку у CATIGraphNode?
Спасибо.
VladimirK
Новичок
Новичок
 
Сообщения: 63
Зарегистрирован: 15 ноя 2011 21:44


Вернуться в CAA-RADE

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 8

cron