Как выполнить сечение CAD-модели
Вопрос от нашего читателя Дмитрия:
Ваши рассуждения верны. Пакет HLR (Hidden Line Removal) библиотеки OpenCascade позволяет получить проекцию видимых очертаний детали на некоторую плоскость. На самом деле есть два алгоритма: HLRBRep_Algo и HLRBRep_PolyAlgo. Первый работает на криволинейном представлении детали, второй — на ее полигонах. Ходят слухи (сам не проверял), что полигональная версия надежнее.
Работа с HLR требует привлечения трех классов:
- HLRBRep_PolyAlgo — собственно алгоритм HLR.
- HLRAlgo_Projector — описывает плоскость проекции.
- HLRBRep_PolyHLRToShape — позволяет извлечь результат как топологическую структуру данных (TopoDS).
Код, приведенный ниже, демонстрирует использование алгоритма в C++.
// Inputs: TopoDS_Shape partShape = ...; // Your TopoDS_Shape. gp_Ax2 axes = ...; // Your projection plane. // Prepare projector. HLRAlgo_Projector projector(axes); // Prepare polygonal HLR algorithm which is known to be more reliable than // the "curved" version of HLR. Handle(HLRBRep_PolyAlgo) polyAlgo = new HLRBRep_PolyAlgo; // polyAlgo->Projector(projector); polyAlgo->Load(partShape); polyAlgo->Update(); // Create topological entities. HLRBRep_PolyHLRToShape HLRToShape; HLRToShape.Update(polyAlgo); // Prepare one compound shape to store HLR results. TopoDS_Compound hlrShape; BRep_Builder().MakeCompound(hlrShape); // Add visible edges to the result. TopoDS_Shape vcompound = HLRToShape.VCompound(); if ( !vcompound.IsNull() ) BRep_Builder().Add(hlrShape, vcompound); // vcompound = HLRToShape.OutLineVCompound(); if ( !vcompound.IsNull() ) BRep_Builder().Add(hlrShape, vcompound);
Переменная hlrShape хранит результат в виде неупорядоченного набора ребер. Эти ребра представлены двумерными параметрическими прямыми, определенными в плоскости проекции.
Ниже приведен сценарий построения плоского сечения в программе «Анализ Положения» (начиная с версии 0.2.6) для тестовой модели ANC101:
# Load sample part. set dir [pwd] clear load-brep $dir/data/cad/ANC101.brep fit # Cut with Boolean operation. set-as-var body make-box tool -25 -25 -25 500 125 250 cut clipped body tool donly clipped set-as-part clipped # Compute HLR. hlr proj 0 0 0 0 -1 0
Инструменты OpenCascade решают чисто геометрическую задачу о нахождении видимых ребер. Алгоритм HLR не наносит штриховок и не рисует осевые линии. Его следует рассматривать только как часть решения проблемы построения чертежей.
2021-05-07 в 01:12:33
Добрый день! По какому принципу можно сделать проекцию нескольких объектов так, чтобы иметь возможность понять какому объекту принадлежат спроецированные элементы?
Я думал, что нужно сделать проекцию каждого объекта в отдельности, но столкнулся с проблемой. При пообъектном проецировании не учитывается то, что проецируемое тело может перекрываться другим, как будто в сцене находится только один объект. Если же проецировать все интересующие тела разом, то не ясно как потом определить какому объекту принадлежат линии. Вот картинка демонстрирующая эти два подхода - https://i.ibb.co/3sHkZtw/pic.png
2021-05-07 в 19:48:03
Я нашел способ, как проецировать объекты по отдельности, чтобы знать какому объекту принадлежат линии проекции.
1) В polyAlgo необходимо добавить все объекты (напр. box и sphere):
Handle(HLRBRep_PolyAlgo) polyAlgo = new HLRBRep_PolyAlgo;
polyAlgo->Projector(projector);
polyAlgo->Load(sphere);
polyAlgo->Load(box);
polyAlgo->Update();
2) Для каждого тела (по отдельности) произвести получение геометрии, передовая в методы VCompound и OutLineVCompound нужные объекты. Ниже я получаю все линии проекция принадлежащие объекту sphere:
TopoDS_Shape vcompound;
vcompound = HLRToShape.VCompound(sphere);
if (!vcompound.IsNull())
BRep_Builder().Add(hlrShape, vcompound);
vcompound = HLRToShape.OutLineVCompound(sphere);
if (!vcompound.IsNull())
BRep_Builder().Add(hlrShape, vcompound);
3) Результат проекции для тела sphere: https://i.ibb.co/P1gyMrC/pic2.png (https://ibb.co/zPZgFmf)
Я все делаю верно или есть более хорошее решение?
2021-05-07 в 21:41:18
Дмитрий, признаюсь, не имею об этом ни малейшего понятия :) Но вопрос хороший, можно повесить вместе с найденным вами решением отдельным постом. Я начал смотреть исходники HLRTest.cxx, и мое внимание привлекла структура HLRTopoBRep_OutLiner, но я не успел с ней поэкспериментировать. Если HLR работает, то хорошо. Производительность там неоптимальная, в любом случае, но для одиночных деталей и маленьких сборок сгодится.
2021-05-08 в 13:00:03
Было бы здорово найти оптимальное решение этой задачи. Я пытался найти, что-то на просторах сети на эту тему, но безрезультатно. Может стоит создать тему на официальном форуме?
Вы ищите какие-то зацепки непосредственно в исходниках? Я использую документацию, но к сожалению она скудна на описания и не ясно, что из себя представляет HLRTopoBRep_OutLiner.