Как назначить новое имя поверхности, заданной в IBody7?

Автор Akew, 27.01.16, 18:33:06

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

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

Akew

Еще один вопрос по поверхностям.

Импортированным поверхностям требуется задать новые имена.

Поверхности я получаю как массив IBody7, доступ к их именам - по свойству Name, - здесь все нормально.
Однако, задать новое имя не удается: не отрабатывает Update() соответствующего IBody7.
Пробовал разные варианты задания имени: и по свойству (->Name = ...), и методами (->put_Name(), ->PutName()), - ничего не выходит.

Пробовал менять имя вручную, непосредственно в дереве, - это тоже не удалось, - курсор в этом поле не появляется, и само поле не редактируется. Удалось изменить имя только через меню "Свойства поверхности".

Как в данной ситуации программно задать новое имя поверхности?

Спасибо!

Прилагаю фрагмент кода и проблемную модель (Оболочка.m3d).

//-------------------------------------------------------------------------------
// Переименовать поверхности через IBody7
// ---
void renameSurfacesByIBody7() {
CString title_dialog = _T( "Функция renameSurfacesByIBody7" );
CString tmpstr;

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 не получен (2)"), title_dialog, MB_OK | MB_ICONERROR); return;
return;
}

IPart7Ptr thisTopPart7 = thisKompasDocument3D->TopPart;
if ( !thisTopPart7 ) {
MessageBox(NULL, _T("*** интерфейс thisTopPart7 не получен (3)"), title_dialog, MB_OK | MB_ICONERROR); return;
return;
}

IFeature7Ptr feature7(IUnknownPtr(ksTransferInterface(thisTopPart7, ksAPI7Dual, 0), false));
if (feature7 == NULL) {
tmpstr.Format(_T("Не удалось получить feature7 (4)") );
MessageBox(NULL, tmpstr, title_dialog, MB_OK|MB_ICONERROR );
return;
}
_variant_t bodies;
feature7->get_ResultBodies(&bodies);

long countBodies = getDimensionVariantArray(bodies); // Определить размерность массива VARIANT
tmpstr.Format(_T("Получено Bodies: %ld"), countBodies ); // Тут все нормально
MessageBox(NULL, tmpstr, title_dialog, MB_OK|MB_ICONINFORMATION );

LPDISPATCH HUGEP *pvar;
HRESULT hr = ::SafeArrayAccessData( bodies.parray, ( void HUGEP* FAR*)&pvar);
if ( ! ( !FAILED( hr ) && pvar ) ) {
return;
}

for ( long i2 = 0; i2 < countBodies; i2++ ) { // Пройти по IBody7, - получить имя и назначить новое
IBody7Ptr body7( pvar[i2] );
if ( !( body7 ) ) {
tmpstr.Format(_T("body7 не получен (i2=%ld)"), i2+1 );
MessageBox(NULL, tmpstr, title_dialog, MB_OK|MB_ICONWARNING );
continue;
}

tmpstr.Format(_T("body7 № %ld: тип: %d, имя: \"%s\""),
i2+1, body7->GetType(), (LPWSTR)body7->GetName() // body7->GetName() показывает нормальное имя
);
// MessageBox(NULL, tmpstr, title_dialog, MB_OK|MB_ICONINFORMATION );

// body7->SetName(_T("Новое Имя")); // Такого метода нет (есть в мануале)

// body7->PutName(_T("Новое Имя")); // Установка имени не проходит
if(!body7->put_Name(_T("Новое Имя")) ) { // ни одним из этих двух способов
tmpstr.Format(_T("Body № %ld: не удалось установить новое имя"), i2+1 );
MessageBox(NULL, tmpstr, title_dialog, MB_OK|MB_ICONWARNING );
// continue;
}

if(!body7->Update() ) { // Update() также не проходит ни в одном из двух способов
tmpstr.Format(_T("Body № %ld: не удалось Update()"), i2+1 ); // (по всей видимости, из-за того что body7 не изменился)
MessageBox(NULL, tmpstr, title_dialog, MB_OK|MB_ICONWARNING );
// continue;
}
}
hr = ::SafeArrayUnaccessData( bodies.parray );

return;
}


Akew

Цитироватьтел здесь уже нет
Я не обратил внимания на эту строчку в дереве.

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


А, где в приведённом выше коде сшивка поверхностей?
По поводу 11009 смотрите сами, но в файле выше такого быть не должно.

Akew

Цитироватьгде в приведённом выше коде сшивка поверхностей?
Ее здесь нет.
Про сшивку я упомянул для примера, когда IBody7 не обязательно должно представлять тело (свой вопрос о сшивках я решил, и пока больше к нему не возвращался).

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

Akew

Обнаружил в своем коде две однотипные ошибки обработки результата вызовов методов put_Name и Update. Они возвращают не BOOL, а HRESULT. Исправил так:HRESULT hr = body7->put_Name(newName); // Установить пользовательское имя телу
if(FAILED(hr)) {
tmpstr.Format(_T("Body № %ld: не удалось установить имя"), i2+1 );
MessageBox(NULL, tmpstr, title_dialog, MB_OK|MB_ICONWARNING );
}

hr = body7->Update(); // Провести изменение в теле
if(FAILED(hr)) {
tmpstr.Format(_T("Body № %ld: не удалось Update()"), i2+1 );
MessageBox(NULL, tmpstr, title_dialog, MB_OK|MB_ICONWARNING );
}


После исправления имя вроде устанавливается, и Update не ругается. Однако, в дереве построения - имя остается прежним.
Тем не менее, при повторном переименовании программа показывает только что установленное новое имя (непосредственно перед переименованием). После сохранения модели и повторном ее открытии все имена остаются прежними.

Если вместо модели с поверхностями взять модель с телами, то все отрабатвается нормально: новое имя тела отображается в дереве тут же.

Так и не понятно, как работать с такими поверхностями.

С одной стороны, это действительно поверхности, т.к. их можно сшивать, и в контектсном меню КОМПАС есть пункт "Свойства ПОВЕРХНОСТИ". Если это так, то тогда к какому типу поверхностей они относятся?

С другой - при получении IFeature7 данный объект имеет тип 11009 (т.е., IBody7). А также операция сшивки (ISurfaceSewer), которая может сшить эти поверхности, требует, чтобы они были представлены как IBody7.

Есть ли у кого какие-нибудь идеи?
Буду признателен за подсказки.

P.S.
Забыл сказать: эти поверхности я получил из сборки, удалив вначале все грани, а потом отобрал те, которые представлены в первом посте. Затем последовательно преобразовал (т.е., сохранил в соответствующем формате) полученную сборку в деталь, в файл STEP 214 и снова в деталь КОМПАС.

Для сшивки поверхности, нужно использовать поверхности, а не тела, я игрался с Вашей сшивкой тел, ISurfaceSewer не требует IBody7, но Вы этот код не показывали, т. ч. Вам и разбираться.

Akew

Sabahs,
повторюсь: вопрос со сшивкой поверхностей, который я задавал в своей предыдущей теме, я решил, и больше он пока не стоит.

Сейчас у меня другая проблема: в приведенной модели нужно назначить другие названия поверхностям (я имею ввиду изменить названия типа "Корпус", "Крышка" и т.д., а не "Экспортированная поверхность:1" и т.д., которые находятся в дереве внутри "Корпуса", "Крышки" и т.д. - как переименовать их, я разобрался). И эту конкретную проблемную модель, и свой код, который призван делать эти переименования, я представил почти полностью (не представленной осталась, например, функция получения размерности массива VARIANT, однако, она непосредственно не относится к проблемному коду).

Конкретно сейчас у меня проблема определить, с чем я имею дело: с телами (IBody7), с поверхностями или чем-то еще. Если с поверхностями, то с какой именно их разновидностью (каково их перечисление в списке ksObj3dTypeEnum, или им подобным)? Пока у меня нет полной ясности.

Вы написали, что
ЦитироватьISurfaceSewer не требует IBody7
Интересно, к какому тогда типу Вы приводили сшиваемые поверхности? Я поначалу приводил к IModelObject, как я это делал ранее с другими операциями с поверхностями, но нужный результат получил только когда привел к IBody7 (об это я рассказал в своей предыдущей теме, непосредственно связанной со сшивками). Мануал гласит, что свойство ISurfaceSewer::Shells возвращает оболочки в виде интерфейсов IBody7. Из этого я заключил, что и сшиваемые поверхности в это свойство должны быть приведены к IBody7. Я так и сделал, и у меня получилось сшить свои поверхности.

Напишите, пожалуйста, что Вам нужно, чтобы помочь мне разобраться в этом вопросе, - я представлю. Или объясните (поправьте, намекните и т.д.), где я ошибся в этом своем изложении, - попытаюсь разобраться самостоятельно.

Спасибо

Я проще делал, у меня были поверхности одного типа, то так Air:=ModelContainer.Objects[o3d_RuledSurface];

Akew

o3d_RuledSurface - это линейчатая поверхность, как я посмотрел в мануале. Но в моей модели таких нет ни одной (во всяком случае, явно созданных операцией "Линейчатая поверхность"). Попробую, конечно, сделать такое преобразование (в понедельник).

А как, все-таки, быть с главным вопросом, то есть, с переименованием этих, то ли поверхностей, то ли деталей?

Такое, Вам не поможет, у Вас есть тело, тело состоит из поверхностей, так сшейте их, указав поверхности, а не тело.

lua

Цитата: Akew от 05.02.16, 21:01:21
А как, все-таки, быть с главным вопросом, то есть, с переименованием этих, то ли поверхностей, то ли деталей?
Поверхность это объект, такой же как и Тело, наверное и переименовать Поверхность можно так же, как переименовываешь Тело...  :~

Akew

ЦитироватьПоверхность это объект, такой же как и Тело, наверное
Пока только больше догадок, чем конкретных инструкций, как достичь желаемого.

Если поверхность, - то какого именно типа (импортированная, линейчатая и т.д.).
Переименовать как тело (IBody7) - не получилось (см. самое первое мое сообщение по этой теме, и пятничное, 05.02., дополнение), хоть и интерфейс IBody7 удалось получить.

И не понятно, в свете сообщения Sabahs, зачем мне что-то сшивать, когда я хочу просто назначить другое имя.
Если в своей оболочке я удалю все поверхности и оставлю только одну (которую уже ни с чем не сошьешь), то как ей назначить новое имя?

lua

Цитата: Akew от 08.02.16, 21:47:00
Если поверхность, - то какого именно типа (импортированная, линейчатая и т.д.).
Что значит какого типа? Мы же не спрашиваем "какого типа тело - выдавливания или вращения?". Для создания тела могут быть применены множество операций. Так и здесь. Получена поверхность. Линейчатая или импортированная - это относится к операциям.