Еще раз про вращение деталей

Автор Akew, 17.02.15, 19:21:54

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

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

Akew

Помогите, пожалуйста, разобраться, почему у меня не работает функция поворота компоненты RotateComponent; поворот компоненты также не происходит. Или приведите фрагмент адекватно работающего кода, - попытаюсь разобраться сам.

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

Работаю в Visual Studio 2005, версия КОМПАСа - 14 SP2. Пробовал этот код в 15 SP1, результат - тот же.
Прилагаю фрагмент кода с комментариями, и архив сборки с компонентной, которую пытаюсь повернуть.
Головной файл этой сборки - это "Сборка с осями.a3d", открывать нужно его.
//-------------------------------------------------------------------------------
// Повернуть компоненту
// ---
void RotationPart() {
CString title_dialog; title_dialog.Format( _T( "Функция %s" ), _T( "RotationPart" ) ); // Заголовок окна сообщений функции (будет выводиться "Функция RotationPart")
CString tmstr;

ksDocument3DPtr cur_doc = MyKompasObject->ActiveDocument3D(); // "MyKompasObject" - это переименованный "kompas" (тип KompsasObject), например, в примере Step3d2 VisualcAUTO; определяется в функции void GetKompas().
if( cur_doc == NULL ) {
MessageBox(NULL, _bstr_t( _T("*** cur_doc == NULL. Выход.") ), title_dialog, MB_OK); return;
}

ksPartPtr part = cur_doc->GetPart( 0 ); // Получить ksPart 1-й компоненты
if ( !part ) {
MessageBox(NULL, _T("*** не удалось получить part. Выход." ), title_dialog, MB_OK); return;
}

tmstr.Format( _T( "Имя компоненты: =%s=." ), (LPWSTR)part->Getname() ); // Показать имя компоненты (для контроля).
MessageBox(NULL, tmstr, title_dialog, MB_OK); // Для прилагаемой сборки выдает "Сборка-оси".

ksComponentPositionerPtr positioner = cur_doc->ComponentPositioner(); // Получить указатель на ksComponentPositioner
if( positioner == NULL ) {
MessageBox(NULL, _bstr_t( _T("*** positioner == NULL. Выход.") ), title_dialog, MB_OK); return;
}

long res = positioner->Prepare( part, pnRotate ); // Подготовиться к операции поворота. Ошибок не возникает.
if( res != 0 ) { // В SDK.chm: 0 - нормальное завершение, 1 - ошибка.
tmstr.Format( _T( "*** positioner->Prepare() не отработал (%ld). Выход." ), res );
MessageBox(NULL, tmstr, title_dialog, MB_OK);
return;
}
// Два предыдущих варианта задания оси поворота.
// if(!(positioner->SetAxisByPoints( 0,0,0,0,0,100 ))) { // Первый - по двум точкам (здесь - ось 0Z).
// if(!(positioner->SetAxis( part->GetDefaultEntity( o3d_axisOZ ) ))) { // Второй - явное указание оси 0Z компоненты.
// Все они отрабатывали без ошибок.

IDispatchPtr axiis = part->GetDefaultEntity( o3d_axisOZ ); // Третий вариант, с отдельным определением оси 0Z компоненты.
if( axiis == NULL ) { // Тоже отрабатывает нормально.
MessageBox(NULL, _bstr_t( _T("*** не удалось получить axiis. Выход.") ), title_dialog, MB_OK); return;
}

if(!(positioner->SetAxis( axiis ))) { // Задание оси по третьему варианту проходит без ошибок (как и по первым двум).
MessageBox(NULL, _T( "*** positioner->SetAxis() не отработал. Выход." ), title_dialog, MB_OK);
return;
}

if(!(positioner->RotateComponent( ( PI*(35.0/180.0) ) ))) { // Указываю поворот на 35 градусов (указываю в радианах, перевод делаю сам; PI - это мое макроопределение, 3.14159..., здесь не приведено).
MessageBox(NULL, _T( "*** positioner->RotateComponent() не отработал." ), title_dialog, MB_OK); // *** ВОТ ЗДЕСЬ ВЫДАЕТ ОШИБКУ! ***
} // Ошибка выдается и для других аргументов: 0.0, 0.1, 0.3 и т.д.

part->UpdatePlacement();
part->Update();

if(!(positioner->Finish())) { // Закончить операцию поворота. Ошибок нет.
MessageBox(NULL, _T( "*** positioner->Finish() не отработал." ), title_dialog, MB_OK);
}

MessageBox(NULL, _bstr_t( _T("Работа по RotationPart завершена.") ), title_dialog, MB_OK);

return;
}

Спасибо всем, кто откликнется.

17.02.15, 19:38:19 #1 Последнее редактирование: 17.02.15, 20:05:44 от Sabahs
Эти две строки нужно убрать.
part->UpdatePlacement();
part->Update();
Строку positioner->Prepare поставить после positioner->SetAxis( axiis ).
Строку part->Update(); поставить после positioner->Finish и по идеи должно работать.

Akew

Спасибо, разобрался, все работает!
Поместил рабочий код в Исходники (http://forum.ascon.ru/index.php/topic,5841.new.html#new).

bbb

Цитата: Akew от 18.02.15, 19:51:08
Спасибо, разобрался, все работает!
Поместил рабочий код в Исходники (http://forum.ascon.ru/index.php/topic,5841.new.html#new).

Попробуйте, повернуть на разные углы и убедитесь, что функция RotateComponent работает неправильно!

P.S. И по поводу перевода градусов в радианы, подключив библиотеку  Math можно использовать константу Pi, а не вводить самому значение числа Пи. Еще  в этой же библиотеке есть функция DegToRad, для перевода градусов в радианы, что избавляет от использования  числа Пи и деления на 180...

Akew

Спасибо за замечание.

bbb, Вы можете указать конкретно, в чем состоит эта неправильность?
Я не разбирался: я получил доступ к нужному интерфейсу, и пока остановился (этот путь решения моей глобальной задачи оказался неправильным).

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


bbb

10.03.15, 15:34:25 #5 Последнее редактирование: 10.03.15, 15:58:04 от bbb
Цитата: Akew от 06.03.15, 19:21:15
Спасибо за замечание.

bbb, Вы можете указать конкретно, в чем состоит эта неправильность?
Я не разбирался: я получил доступ к нужному интерфейсу, и пока остановился (этот путь решения моей глобальной задачи оказался неправильным).

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



Неправильность заключается в том что функция RotateComponent поворачивает на неправильный угол... :)
см. тему http://forum.ascon.ru/index.php/topic,141.20.html (был создан запрос в SD на эту тему)

Vitalij Lysanov

Вращение на 360 градусов
                       x=x1-math.cos((masht-200.0)/80.0)
                  print "uuuuuu",(masht-200.0)/80.0
                  y=y1
                  z=z1+math.sin((masht-200.0)/80.0)
                  iplac.SetAxis(x, y, z,0)
                  iPart.SetPlacement(iplac)
                  iPart.UpdatePlacement()
                  iplac.SetOrigin(x1, y1, z1)
                  iPart.Update()
           
Полный оборот за 6.28.
В приложении робот с вращающимися ногами.
Макрос работает из режима редактирования на сборке робота.
После одной поездки снимать Диспетчером Компас т.к  Компас работает с вершиной стека, а остальных погружает все глубже.
Для ускорение движения робота нажать крестик выхода окна Компаса, появится окно с предложение сохранить и одновременно увеличится скорость в пять раз, можно так продолжать работать но проблема с зависанием машины остается.
Начальные координаты компонент берутся из файла на диске "С:\"