Форум пользователей ПО АСКОН

Профессиональные вопросы => Программирование приложений => Тема начата: Akew от 30.03.16, 19:56:49

Название: Вопрос: Как не закрывая "отдать" взятый в обработку документ
Отправлено: Akew от 30.03.16, 19:56:49
Добрый вечер!

В окне КОМПАС открыта 3D модель. Получаю к ней доступ:
ksDocument3DPtr doc3D = MyKompasObject->ActiveDocument3D();
if( doc3D != NULL ) {

IKompasDocument3DPtr kompasDoc3D( IUnknownPtr( ksTransferInterface( doc3D, ksAPI7Dual, 0), false) );
if( kompasDoc3D != NULL ) {

IPart7Ptr part7 = kompasDoc3D->TopPart;
if( part7 != NULL ) {

// Обработка компонент

}
}
}


Проблема состоит в том, что блок "Обработка компонент" кроме чисто программных методов обработки имеет операции КОМПАСа, которые интерактивно вызывает пользователь (с панелей инструментов КОМПАСа).
Например, редактирование операции "Удалить грани"; после возобновления автоматической обработки программа определяет изменения в этой операции (т.е., находит, какие грани были удалены/восстановлены, по ним находит стыкующиеся грани и удаляет эти грани из массива операции "Удалить грани", и др.).
Взаимодействие с пользователем реализовано на выдаче немодального сообщения; работа программы приостанавливается, пока пользователь не проведет свою операцию и не закроет это сообщение (кнопка "OK").

В связи с этим, вопрос: должна ли программа каким-то образом возвращать текущий документ, перед тем как пользователь будет редактировать операцию "Удалить грани"? Я полагаю, что должна. Только пока не нашел подходящего способа; есть только метод close(), но мне хотелось бы, чтобы документ оставался открытым в окне КОМПАСа (не открывать его снова всякий раз).

Спасибо.
Название: Re: Вопрос: Как не закрывая "отдать" взятый в обработку документ
Отправлено: Sabahs от 30.03.16, 20:01:06
Она у Вас, что отдельным потоком работает?
Название: Re: Вопрос: Как не закрывая "отдать" взятый в обработку документ
Отправлено: Akew от 30.03.16, 20:16:20
ЦитироватьОна у Вас, что отдельным потоком работает?
Нет, вряд ли (во всяком случае, я ничего не организовывал). И с таким понятием, поток, пока не сталкивался.
Название: Re: Вопрос: Как не закрывая "отдать" взятый в обработку документ
Отправлено: Sabahs от 30.03.16, 21:06:39
Тогда, я не понимаю сути проблемы.
Название: Re: Вопрос: Как не закрывая "отдать" взятый в обработку документ
Отправлено: Akew от 30.03.16, 21:57:10
Цитировать
Цитата: Sabahs от 30.03.16, 21:06:39
Тогда, я не понимаю сути проблемы.
Я подозреваю, что, когда программа (в том виде, в каком она реализована сейчас) "отдает управление" пользователю, то редактируемая 3D модель, уже "занятая" программой, пользователю передается, как бы, не в полном объеме (как это было бы в случае, если пользователь с самого начала редактировал ее вручную, без использования программы). Например, при ручном редактировании операции "Удалить грани" (при работе с программой) не всегда показывается кол-во удаленных граней в окошке свойств этой операции (сами грани при этом отбираются нормально); нельзя построить кривую пересечения двух поверхностей и т.д.. Эти ситуации похожи на те, когда, не закончив редактирование одной операции (например, забыв закончить), пользователь начинает работать с другой (при "ручной" работе с КОМПАС).

Мне нужен способ отдачи пользователю полного управления над редактируемой моделью от программы, и получения его обратно, когда он закончит свои действия (не закрывая при этом программы, и без повторного закрывания-открывания редактируемой модели в окне КОМПАСа).
Название: Re: Вопрос: Как не закрывая "отдать" взятый в обработку документ
Отправлено: Sabahs от 30.03.16, 22:03:31
Что делает пользователь, можно контролировать. Без кода тут бессмысленно разговаривать, я не могу понять, зачем закрывать программу, а также закрывать и открывать деталь?
Название: Re: Вопрос: Как не закрывая "отдать" взятый в обработку документ
Отправлено: Akew от 31.03.16, 18:01:52
Цитата: Sabahs от 30.03.16, 22:03:31
Без кода тут бессмысленно разговаривать
Вот, извольте.
В программе реализован интерактивный цикл (функция RunInteractiveCycle()).
//------------------------------------------------------------------------------
// Запустить интерактивный цикл
// ---
void RunInteractiveCycle() {
CString title_dialog = _T( "Функция RunInteractiveCycle" );

// Проверить, открыта ли модель, получить к ней доступ
ksDocument3DPtr thisDocument3D( MyKompasObject->ActiveDocument3D() );
if ( !thisDocument3D ) {
MessageBox( NULL, _T("thisDocument3D не получен (1)"), title_dialog, MB_OK|MB_ICONERROR ); return;
}

IKompasDocument3DPtr thisKompasDocument3D = IUnknownPtr( ksTransferInterface( thisDocument3D, ksAPI7Dual, 0), false);
if ( !thisKompasDocument3D ) {
MessageBox( NULL, _T("thisKompasDocument3D не получен (5)"), title_dialog, MB_OK|MB_ICONERROR ); return;
}

IPart7Ptr topPart7 = thisKompasDocument3D->TopPart;
if ( !topPart7 ) {
MessageBox( NULL, _T("topPart7 не получен (6)"), title_dialog, MB_OK|MB_ICONERROR ); return;
}

// Интерактивный цикл, пока пользователь его не остановит в диалоге-запросе
while(1) {
// 1. Выдать первый диалог (немодальный), чтобы пользователь провел операции с открытой моделью в КОМПАСе
MessageBox( NULL, _T("Работа программы приостановлена\n\nПроведите манипуляцию с моделью, вернитесь к этому сообщению и нажмите OK"), title_dialog, MB_OK|MB_ICONINFORMATION );

// 2. Программа возобновляет работу, определяет сделанные пользователем изменения с моделью и проводит с ней определенные действия

// 3. Выдать второй диалог (модальный) с запросом, продолжать ли интерактивный цикл; получить отклик
if ( MessageBox( ::GetActiveWindow(), _T("Закончить интерактивный цикл?"),
_T("Вопрос"), MB_ICONQUESTION | MB_YESNO ) == IDYES ) break;

}
// Конец работы с интерактивным циклом

MessageBox( NULL, _T("Работа цикла закончена"), title_dialog, MB_OK|MB_ICONINFORMATION );

}

Это бесконечный while с двумя диалогами-сообщениями.
Первый - для организации пользовательской паузы, во время которой пользователь выполняет те или иные операции в КОМПАС (редактирует открытую модель).
Пауза прерывается нажанием OK в этом диалоге.
Второй - с вопросом, продолжать ли интерактивный цикл. Если нет, то - выход из него.

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

В отсутствие программы - кривые строятся без проблем.
При запуске этого цикла - те же самые кривые не создаются. Наборы поверхностей - указываются, - и образ будущей кривой пересечения вроде бы появляется. Однако, кнопка "Создать объект" панели свойств остается неактивной.
Кроме того, в окошках наборов поверхностей иногда не появляются названия поверхностей, которые были указаны как исходные.

Эта проблема, как оказалось, серьезнее, чем представлялась вначале. А именно, если изначально модель в КОМПАСе не открывать, а в функции RunInteractiveCycle() убрать проверку наличия открытой модели, а во время пользовательской паузы открыть ту же модель, то построить кривую пересечения двух поверхностей тоже не удастся, - хотя, казалось бы, пользователь получает непосредственный доступ к модели. Таким образом, манипуляции с закрыванием-открыванием открытой модели не помогли бы.
В связи с этим, мой вопрос нужно сформулировать иначе: "Как получить доступ к моделям из интерактивного цикла?".

Прилагаю полный проект и образец модели, на которой наблюдал описанные феномены (Windows XP, Visual C++ 2005, КОМПАС v14).
В качестве первого набора поверхностей нужно указать плоскость ZX, второго - самые большие грани "кирпича" или шар (возможны и иные варианты). Как образец, одна такая кривая уже построена (на шаре).

P.S. Вы написали, что "Что делает пользователь, можно контролировать".
Как в приведенном интерактивном цикле можно проконтролировать, что пользователь завершил операцию "Кривая пересечения поверхностей", т.е., нажал "Создать объект" или "Прервать команду" (если этот вопрос не является отдельной темой)?
Название: Re: Вопрос: Как не закрывая "отдать" взятый в обработку документ
Отправлено: Sabahs от 01.04.16, 06:05:25
Т.е. Вы хотите сказать, что - MessageBox, штука не модальная?
По моему, проще сделать не модальную форму, кинуть на неё кнопку, по нажатию которой библиотека получит доступ к документу и сделает свои манипуляции, а наличие крестика поможет отключить библиотеку.
http://forum.ascon.ru/index.php/topic,22654.msg155743.html#msg155743 (http://forum.ascon.ru/index.php/topic,22654.msg155743.html#msg155743)
Название: Re: Вопрос: Как не закрывая "отдать" взятый в обработку документ
Отправлено: Akew от 01.04.16, 20:43:33
Цитата: Sabahs от 01.04.16, 06:05:25
Т.е. Вы хотите сказать, что - MessageBox, штука не модальная?
Насколько я знаю, все зависит от 1-го аргумента, указателя на родителя.
Если это будет реальный родитель, т.е.,::GetActiveWindow(), то MessageBox будет модальным.
Если NULL, то - не модальным.

ЦитироватьПо моему, проще сделать не модальную форму, кинуть на неё кнопку, по нажатию которой библиотека получит доступ к документу и сделает свои манипуляции, а наличие крестика поможет отключить библиотеку.
Поясните, пожалуйста:
1. Чем Ваша реализация будет отличаться от моей представленной? У моей формы, в MessageBox (тот, что первый), тоже есть кнопка, OK, после нажатия которой управление получает программа.
2. Не понял, для чего нужно отключать библиотеку (по "крестику"): в общем случае, после окончания работы с циклом пользователь должен иметь возможность продолжить работу с другими функциями библиотеки (включая и эту, с циклом).

Прием использования нескольких окон интересный, только пока не понял, как его приспособить к моей задаче.

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

Спасибо.
Название: Re: Вопрос: Как не закрывая "отдать" взятый в обработку документ
Отправлено: Sabahs от 01.04.16, 21:19:22
Вы свой результат уже получили, иногда мелочи, которых Вы не показываете, играют немаловажную роль.
PS. Я показывал просто вариант и кое какие, мелочи - это не означает,  что надо делать так, а не иначе.
Название: Re: Вопрос: Как не закрывая "отдать" взятый в обработку документ
Отправлено: Akew от 01.04.16, 22:18:53
Цитата: Sabahs от 01.04.16, 21:19:22
Вы свой результат уже получили, иногда мелочи, которых Вы не показываете, играют немаловажную роль.
Нужного результата, построение пользователем кривых в интерактивном цикле, нет.

Какие мелочи я не показал? Блок, который обрабатывает ("отлавливает") отстроенные пользователем кривые? А для решения данной вопроса он и не нужен, т.к. проблема в том, что пользователь не может построить эти кривые до этого блока, - сейчас у меня проблема только в этом.

Однако, если Вам нужна дополнительная информация ("мелочи"), то, пожалуйста, уточните, что именно, - представлю. Пока не понятно, что требуется (код - есть, модель - тоже, проблему описал, надеюсь, достаточно подробно).
Название: Re: Вопрос: Как не закрывая "отдать" взятый в обработку документ
Отправлено: Sabahs от 02.04.16, 05:50:33
Я считаю, что такая реализация, как сделана у Вас, является неправильной, где Вы передали управление из Вашего цикла, Компасу?
Оптимальный вариант смотреть в сторону событий Компаса, тем более там уже эти циклы присутствуют, перейдите по ссылке ниже, там есть кино, где показано, как это работает в отладчике.
http://forum.ascon.ru/index.php/topic,29269.msg224103.html#msg224103 (http://forum.ascon.ru/index.php/topic,29269.msg224103.html#msg224103)