У меня есть тесселяционная сфера OpenGL, и я хочу вырезать в ней цилиндрическое отверстие
Я работаю над программным обеспечением, которое сгенерировало полигональную сетку для представления сферы, и я хочу вырезать дыру в сфере. Эта полигональная сетка является только наложением на поверхность сферы. У меня есть хорошая идея, как определить, какие полигоны будут пересекать мою дыру, и я могу удалить их из своей коллекции, но после этого я немного запутался. Мне было интересно, может ли кто-нибудь помочь мне с концепциями высокого уровня?
По сути, я представляю три ситуации:
1.) The cylindrical hole does not intersect my sphere.
2.) The cylindrical hole partially goes through my sphere.
3.) The cylindrical hole goes all the way through my sphere.
Для #1 я могу проверить это (многоугольники не удалены) и действовать соответственно (ничего не делать). Что касается № 2 и № 3, я не уверен, как изменить тесселяцию моей сферы для учета дыры. Для #3 у меня есть идея, которая в основном заключается в следующем:
a.) Find your entry point (a circle)
b.) Find your exit point (a circle)
c.) Remove the necessary polygons
d.) Make new polygons along the 4* 'sides' of the hole to keep my
sphere a manifold.
У этого чрезвычайно упрощенного алгоритма есть некоторые "дыры", которые я хотел бы заполнить. Например, я не хочу, чтобы в моей дыре было 4 стороны - это должен быть цилиндр или, по сути, мозаичное представление цилиндра. Я также не уверен, как сделать из этих новых многоугольников мою сферу с дырой в мозаичной поверхности.
Я понятия не имею, как подходить к сценарию № 2.
3 ответа
Похоже, вы хотите конструктивную твердую геометрию.
Carve может делать то, что вы хотите. Если вы просто хотите рендеринг во время выполнения, OpenCSG будет работать.
Ну, если вы хотите просто визуализировать это (визуализировать), то, возможно, вам вообще не нужно менять сгенерированные сетки. Вместо этого используйте буфер трафарета, чтобы визуализировать сферу с отверстиями. Например я рендеринг диска (тонкий цилиндр) с круглыми отверстиями вблизи его внешнего края (в качестве опорной пластины для машин) с комбинацией твердых и прозрачных объекты вокруг так, мне нужно отверстие действительно отверстие. Поскольку мне было лень триангулировать форму, которая генерируется во время выполнения, я выбрал трафарет для этого.
Создать контекст OpenGL с помощью буфера трафарета
Я использую 8 бит для трафарета, но эта техника использует только один бит.
Очистить трафарет с
0
и отключите маски глубины и цветаЭто должно быть сделано до рендеринга вашей сетки с трафаретом. Так что, если у вас есть больше объектов, отображаемых таким образом, вам нужно сделать это перед каждым из них.
Установить трафарет с
1
для сплошной сетки- Очистить трафарет с
0
для ячеистых сеток - Включите маски глубины и цвета и визуализируйте сплошную сетку там, где
1
В коде это выглядит так:
// [stencil]
glEnable(GL_STENCIL_TEST);
// whole stencil=0
glClearStencil(0);
glClear(GL_STENCIL_BUFFER_BIT);
// turn off color,depth
glStencilMask(0xFF);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glDepthMask(GL_FALSE);
// stencil=1 for solid mesh
glStencilFunc(GL_ALWAYS,1,0xFF);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
glCylinderxz(0.0,y,0.0,r,qh);
// stencil=0 for hole meshes
glStencilFunc(GL_ALWAYS,0,0xFF);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
for(b=0.0,j=0;j<12;j++,b+=db)
{
x=dev_R*cos(b);
z=dev_R*sin(b);
glCylinderxz(x,y-0.1,z,dev_r,qh+0.2);
}
// turn on color,depth
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDepthMask(GL_TRUE);
// render solid mesh the holes will be created by the stencil test
glStencilFunc(GL_NOTEQUAL,0,0xFF);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
glColor3f(0.1,0.3,0.4);
glCylinderxz(0.0,y,0.0,r,qh);
glDisable(GL_STENCIL_TEST);
где glCylinderxz(x,y,z,r,h)
это просто функция, которая делает цилиндр в (x,y,z)
с радиусом r
с y
ось как его ось вращения. db
шаг угла (2*Pi/12)
, Радиусы r
-большой, dev_r
радиус отверстия, dev_R
центры А qh
толщина пластины
Результат выглядит следующим образом (каждая из 2-х пластин визуализируется с этим):
Этот подход больше подходит для тонких объектов. Если ваши порезы приводят к достаточно толстым сторонам, то вам нужно добавить рендеринг срезанной стороны, иначе освещение на этих деталях может быть неправильным
Я реализовал операции CSG, используя скалярные поля ранее в этом году. Это работает хорошо, если производительность не важна. То есть расчеты не в реальном времени. Проблема в том, что производная не везде определена, поэтому вы можете забыть о вычислении дешевых нормалей вершин таким образом. Это должно быть сделано в качестве пост-шага. Смотрите здесь для бумаги, которую я использовал (в первом ответе), и некоторые скриншоты, которые я сделал:
CSG-операции на неявных поверхностях с марширующими кубами
Кроме того, CSG таким образом требует, чтобы начальная сетка была представлена с использованием неявных поверхностей. Хотя любую геометрическую сетку можно разбить на плоскости, это не даст хороших результатов. Таким образом, сферы должны были бы быть представлены радиусом и началом координат, а цилиндры были бы представлены радиусом, началом и высотой основания.