• Добро пожаловать на Форум пользователей ПО АСКОН. Пожалуйста, авторизуйтесь.
 

Уважаемые пользователи,

Хотим проинформировать вас о режиме работы регистрации на нашем сайте.

Зарегистрироваться возможно в рабочие дни, с 8:00 до 20:00 (мск).

Если у вас возникнут вопросы или потребуется дополнительная информация, не стесняйтесь обращаться к нашей службе поддержки. Вы можете связаться с нами по указанным контактным данным на нашем сайте.

Благодарим вас за понимание и сотрудничество. Мы ценим ваше терпение и стремимся предоставить вам лучший опыт использования нашего сервиса.

С уважением,
Команда Ascon

Как преобразовать пространственную окружность в ksCurve3D?

Автор Akew, 12.09.16, 17:48:35

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

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

Akew

Требуется получить грани сборки, пересеченные окружностью.

В прилагаемой модели (открывать "Три кубика и окружность v14.2.a3d") ожидаю получить шесть граней (по две грани от каждого из трех кубиков).

Решение задачи определения граней сборки, пересеченных прямой, у меня есть. Оно состоит в вызове метода
BOOL CurveIntersection (LPDISPATCH curve,
LPDISPATCH parts,
LPDISPATCH fases,
LPDISPATCH points)
для topRart сборки.

Пытаюсь тот же метод применить для окружности.
Суть проблемы состоит в том, что не могу найти способ преобразования окружности в ksCurve3D.
Получаю доступ к созданной окружности и как к ksEntity типа o3d_curveElement:
ksDocument3DPtr document3d = KompasObject->ActiveDocument3D();
if( !document3d ) {
MessageBox(NULL, _T("document3d не получен. Выход"), title_dialog, MB_OK|MB_ICONWARNING ); return;
}

IKompasDocument3DPtr kompDoc3D( IUnknownPtr( ksTransferInterface( document3d, ksAPI7Dual, 0), false) );
if ( !kompDoc3D ) {
MessageBox(NULL, _T("kompDoc3D не получен. Выход"), title_dialog, MB_OK|MB_ICONWARNING ); return;
}

ksPartPtr topPart = document3d->GetPart( pTop_Part );
if ( !topPart ) {
MessageBox(NULL, _T("topPart не получен. Выход"), title_dialog, MB_OK|MB_ICONWARNING ); return;
}

ksEntityCollectionPtr entityCollection( topPart->EntityCollection( o3d_curveElement ));
if ( !entityCollection ) {
MessageBox(NULL, _T("entityCollection не получен. Выход"), title_dialog, MB_OK|MB_ICONWARNING ); return;
}

ksEntityPtr circleAsEntity(entityCollection->GetByName( _bstr_t( _T("Окружность вокруг ребра")), TRUE, FALSE ));
if ( !circleAsEntity ) {
MessageBox(NULL, _T("circleAsEntity не получен. Выход"), title_dialog, MB_OK|MB_ICONWARNING ); return;
}

// ksCurve3DPtr circleAsCurve3D = MyKompasObject->TransferInterface( circleAsEntity, ksAPI5Auto, o3d_curve3D ); // Так не получается
ksCurve3DPtr circleAsCurve3D = MyKompasObject->TransferInterface( circleAsEntity, ksAPI5Auto, o3d_curveElement ); // Так - тоже
if ( !circleAsCurve3D ) {
MessageBox(NULL, _T("circleAsCurve3D не получен. Выход"), title_dialog, MB_OK|MB_ICONWARNING ); return; // Завершение работы здесь
}

// Получить пересечения окружностью граней сборки
ksPartCollectionPtr part_collection = document3d->PartCollection( false ); // 1. Массив деталей
ksFaceCollectionPtr face_collection = document3d->GetInterface( o3d_faceCollection ); // 2. Массив граней
ksCoordinate3dCollectionPtr points_collection = document3d->GetInterface( o3d_coordinate3dCollection ); // 3. Массив точек, который будет заполнен

// Получение пересечений
if( topPart->CurveIntersection(
circleAsCurve3D,
part_collection,
face_collection,
points_collection
) ) {
tmpstr.Format( _T("Пересечений: %ld"), points_collection->GetCount() );
MessageBox(NULL, tmpstr, title_dialog, MB_OK|MB_ICONINFORMATION );
} else {
tmpstr.Format( _T("Пересечений нет") );
MessageBox(NULL, tmpstr, title_dialog, MB_OK|MB_ICONINFORMATION );
}

и как к дуге из коллекции дуг из вспомогательной геометрии (тип IArc3D):
ksDocument3DPtr document3d = KompasObject->ActiveDocument3D();
if( !document3d ) {
MessageBox(NULL, _T("document3d не получен. Выход"), title_dialog, MB_OK|MB_ICONWARNING ); return;
}

IKompasDocument3DPtr kompDoc3D( IUnknownPtr( ksTransferInterface( document3d, ksAPI7Dual, 0), false) );
if ( !kompDoc3D ) {
MessageBox(NULL, _T("kompDoc3D не получен. Выход"), title_dialog, MB_OK|MB_ICONWARNING ); return;
}

IPart7Ptr topPart7 = kompDoc3D->TopPart;
if ( !topPart7 ) {
MessageBox(NULL, _T("topPart7 не получен. Выход"), title_dialog, MB_OK|MB_ICONWARNING ); return;
}

IAuxiliaryGeomContainerPtr auxiliaryGeometryContainer = topPart7;
if ( !auxiliaryGeometryContainer ) {
MessageBox(NULL, _T("auxiliaryGeometryContainer не получен. Выход"), title_dialog, MB_OK|MB_ICONWARNING ); return;
}

IArcs3DPtr arcs3D = auxiliaryGeometryContainer->GetArcs3D();
if ( !arcs3D ) {
MessageBox(NULL, _T("arcs3D не получен. Выход"), title_dialog, MB_OK|MB_ICONWARNING ); return;
}

IArc3DPtr arc3D = arcs3D->GetArc3D( 0 ); // Берем первую дугу
if ( !arc3D ) {
MessageBox(NULL, _T("arc3D не получен. Выход"), title_dialog, MB_OK|MB_ICONWARNING ); return;
}

// ksCurve3DPtr circleAsCurve3D = MyKompasObject->TransferInterface( arc3D, ksAPI5Auto, o3d_curveElement ); // Так не получается
ksCurve3DPtr circleAsCurve3D = MyKompasObject->TransferInterface( arc3D, ksAPI5Auto, o3d_curve3D ); // Так - тоже
if ( !circleAsCurve3D ) {
MessageBox(NULL, _T("circleAsCurve3D не получен. Выход"), title_dialog, MB_OK|MB_ICONWARNING ); return; // Завершение работы здесь
}

// Получить пересечения окружностью граней сборки
ksPartCollectionPtr part_collection = document3d->PartCollection( false ); // 1. Массив деталей
ksFaceCollectionPtr face_collection = document3d->GetInterface( o3d_faceCollection ); // 2. Массив граней
ksCoordinate3dCollectionPtr points_collection = document3d->GetInterface( o3d_coordinate3dCollection ); // 3. Массив точек, который будет заполнен

// Получение пересечений
ksPartPtr topPart = document3d->GetPart( pTop_Part );
if ( !topPart ) {
MessageBox(NULL, _T("topPart не получен. Выход"), title_dialog, MB_OK|MB_ICONWARNING ); return;
}

if( topPart->CurveIntersection(
circleAsCurve3D,
part_collection,
face_collection,
points_collection
) ) {
tmpstr.Format( _T("Пересечений: %ld"), points_collection->GetCount() );
MessageBox(NULL, tmpstr, title_dialog, MB_OK|MB_ICONINFORMATION );
} else {
tmpstr.Format( _T("Пересечений нет") );
MessageBox(NULL, tmpstr, title_dialog, MB_OK|MB_ICONINFORMATION );
}

Но получить из них обоих ksCurve3D так и не удается.

Раньше, когда в качестве кривой я использовал прямую по двум точкам, типа ksAxis2PointsDefinitionPtr, у нее был метод получения ее ksCurve3D GetCurve3D().

Помогите, пожалуста, найти подобный метод для окружности, или предложите иной вариант решения.
Спасибо.

P.S. Нужен именно массив граней, а не построение точки пересечения кривой с поверхностью.

333

Преобразовать нужно к IModelObject
Затем получить дополнительный интерфейс IModelObject1
Кривую ICurve3D вернет метод IModelObject1::MathObject
IArc3DPtr arc3D = arcs3D->GetArc3D( 0 );
IModelObject1Ptr obj1 ( arc3D );
if ( obj1 )
{
  ICurve3DPtr curve3D(  obj1->MathObject );
  ...
При необходимости можно сделать TransferInterface  c curve3D и получить ksCurve3D

Вариант 2:
Получить с фичи дуги ребро o3d_edge и работать через ksEdgeDefinition::GetCurve
+ Благодарностей: 1

Akew

Спасибо за подсказки, 333.

Из предложенных Вами вариантов у меня получился только первый, с использованием IModelObject1::GetMathObject().
К сожалению, этот метод реализован только в 16-й версии КОМПАСа, а программа создается для 15-го.

Второй Ваш вариант я реализовал в двух видах. Я не понял, что конкретно означает "фича", догадался только, что это, вероятно ksFeature или IFeature7. В обоих этих версиях загвоздка возникает на шаге получения ksEdgeDefinition.

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

Общий код для всех вариантов (проверка наличия дуг (IArc3D) в модели и выбор первой из них):
CString title_dialog = "Функция определения пересечений окружности с моделью";

ksDocument3DPtr document3d = MyKompasObject->ActiveDocument3D();
if( !document3d ) {
MessageBox(NULL, _T("document3d не получен. Выход"), title_dialog, MB_OK|MB_ICONWARNING ); return;
}

IKompasDocument3DPtr kompDoc3D( IUnknownPtr( ksTransferInterface( document3d, ksAPI7Dual, 0), false) );
if ( !kompDoc3D ) {
MessageBox(NULL, _T("kompDoc3D не получен. Выход"), title_dialog, MB_OK|MB_ICONWARNING ); return;
}

IPart7Ptr topPart7 = kompDoc3D->TopPart;
if ( !topPart7 ) {
MessageBox(NULL, _T("topPart7 не получен. Выход"), title_dialog, MB_OK|MB_ICONWARNING ); return;
}

IAuxiliaryGeomContainerPtr auxiliaryGeometryContainer = topPart7;
if ( !auxiliaryGeometryContainer ) {
MessageBox(NULL, _T("auxiliaryGeometryContainer не получен. Выход"), title_dialog, MB_OK|MB_ICONWARNING ); return;
}

IArcs3DPtr arcs3D = auxiliaryGeometryContainer->GetArcs3D();
if ( !arcs3D ) {
MessageBox(NULL, _T("arcs3D не получен. Выход"), title_dialog, MB_OK|MB_ICONWARNING ); return;
}

if( arcs3D->GetCount() == 0 ) {
MessageBox(NULL, _T("В модели нет ни одной дуги (IArcs3D). Выход"), title_dialog, MB_OK|MB_ICONWARNING ); return;
}

IArc3DPtr arc3D = arcs3D->GetArc3D( 0 ); // Взять первую дугу
if ( !arc3D ) {
MessageBox(NULL, _T("arc3D не получен. Выход"), title_dialog, MB_OK|MB_ICONWARNING ); return;
}


Вариант 1: получить ksCurve3D дуги посредством IModelObject1 (тут ошибок нет, все работает, - код для интересующихся):
IModelObject1Ptr arc3DasModelObject1( arc3D );
if ( !arc3DasModelObject1 ) {
MessageBox(NULL, _T("arc3DasModelObject1 не получен. Выход"), title_dialog, MB_OK|MB_ICONWARNING ); return;
}

IKompasAPIObjectPtr arc3DasKompasAPIObject ( arc3DasModelObject1->GetMathObject() ); // !Метод реализован только в 16-м КОМПАСе
if ( !arc3DasKompasAPIObject ) {
MessageBox(NULL, _T("arc3DasKompasAPIObject не получен. Выход"), title_dialog, MB_OK|MB_ICONWARNING ); return;
}

if( arc3DasKompasAPIObject->GetType() != ksObjectMathCurve3D ) {
MessageBox(NULL, _T("Полученный объект не является кривой. Выход"), title_dialog, MB_OK|MB_ICONWARNING ); return;
}

ksCurve3DPtr arc3DasCurve3D = MyKompasObject->TransferInterface( arc3DasModelObject1, ksAPI5Auto, o3d_curve3D );
if ( !arc3DasCurve3D ) {
MessageBox(NULL, _T("arc3DasCurve3D не получен. Выход"), title_dialog, MB_OK|MB_ICONWARNING ); return;
}


Вариант 2 (два под-варианта):
ЦитироватьПолучить с фичи дуги ребро o3d_edge и работать через ksEdgeDefinition::GetCurve
Под-вариант 1:
// 2.1. Под-вариант 1: Если "фича" - ksFeature, то:
// 2.1.1 Получить ksFeature дуги
ksEntityPtr arc3DasEntity = MyKompasObject->TransferInterface( arc3D, ksAPI5Auto, o3d_entity );
if ( !arc3DasEntity ) {
MessageBox(NULL, _T("arc3DasEntity не получен. Выход"), title_dialog, MB_OK|MB_ICONWARNING ); return;
}

ksFeaturePtr arc3DasFeature = arc3DasEntity->GetFeature();
if ( !arc3DasFeature ) {
MessageBox(NULL, _T("arc3DasFeature не получен. Выход"), title_dialog, MB_OK|MB_ICONWARNING ); return;
}

// 2.1.2. Получить o3d_edge с фичи дуги
ksEdgeDefinitionPtr arc3DasEdgeDefinition = MyKompasObject->TransferInterface( arc3DasFeature, ksAPI5Auto, o3d_edge );
if ( !arc3DasEdgeDefinition ) {
MessageBox(NULL, _T("arc3DasEdgeDefinition не получен. Выход"), title_dialog, MB_OK|MB_ICONWARNING ); return;
}

// 2.1.3. Получить ksCurve3D с o3d_edge
ksCurve3DPtr arc3DasCurve3D = MyKompasObject->TransferInterface( arc3DasEdgeDefinition, ksAPI5Auto, o3d_curve3D );
if ( !arc3DasCurve3D ) {
MessageBox(NULL, _T("arc3DasCurve3D не получен. Выход"), title_dialog, MB_OK|MB_ICONWARNING ); return; // Завершение работы здесь
}


Под-вариант 2:
// 2.2. Под-вариант 2: Если "фича" - IFeature7, то:
// 2.2.1 Получить IFeature7 дуги
IModelObjectPtr arc3DasModelObject( arc3D );
if ( !arc3DasModelObject ) {
MessageBox(NULL, _T("arc3DasModelObject не получен. Выход"), title_dialog, MB_OK|MB_ICONWARNING ); return;
}

IFeature7Ptr arc3DasFeature7 = arc3DasModelObject->GetOwner();
if ( !arc3DasFeature7 ) {
MessageBox(NULL, _T("arc3DasFeature7 не получен. Выход"), title_dialog, MB_OK|MB_ICONWARNING ); return;
}

// 2.2.2. Получить o3d_edge с фичи дуги
ksEdgeDefinitionPtr arc3DasEdgeDefinition = MyKompasObject->TransferInterface( arc3DasFeature7, ksAPI5Auto, o3d_edge );
if ( !arc3DasEdgeDefinition ) {
MessageBox(NULL, _T("arc3DasEdgeDefinition не получен. Выход"), title_dialog, MB_OK|MB_ICONWARNING ); return;
}

// 2.2.3. Получить ksCurve3D с o3d_edge (идентично 2.1.3)
ksCurve3DPtr arc3DasCurve3D = MyKompasObject->TransferInterface( arc3DasEdgeDefinition, ksAPI5Auto, o3d_curve3D );
if ( !arc3DasCurve3D ) {
MessageBox(NULL, _T("arc3DasCurve3D не получен. Выход"), title_dialog, MB_OK|MB_ICONWARNING ); return; // Завершение работы здесь
}


Спасибо!

P.S. Еще у меня получился способ, когда в модели я вначале нахожу ребра (коллекция ksEntityCollection из o3d_Edge), среди них нахожу окружность, преобразую это ребро в ksEdgeDefinition и получаю ksCurve3D. Однако это слишком громоздкий способ, требующий перебора всех ребер модели, чтобы найти среди них нужную окружность. Хотелось бы научиться преобразовывать окружность напрямую.