У меня есть тесселяционная сфера OpenGL, и я хочу вырезать в ней цилиндрическое отверстие - PullRequest
1 голос
/ 19 октября 2010

Я работаю над программным обеспечением, которое сгенерировало полигональную сетку для представления сферы, и я хочу вырезать дыру в сфере.Эта полигональная сетка является наложением только на поверхность сферы.У меня есть хорошая идея, как определить, какие полигоны будут пересекать мою дыру, и я могу удалить их из своей коллекции, но после этого я немного запутался.Мне было интересно, может ли кто-нибудь помочь мне с концепциями высокого уровня?

В принципе, я представляю три ситуации:

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 ]

2 голосов
/ 19 октября 2010

Звучит так, как вы хотите конструктивная геометрия твердого тела .

Carve может делать то, что вы хотите. Если вы просто хотите, чтобы рендеринг во время выполнения OpenCSG работал.

1 голос
/ 13 сентября 2016

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

  1. Создание контекста OpenGL с буфером трафарета

    IЯ использую 8 бит для трафарета, но этот метод использует только один бит.

  2. Очистить трафарет с помощью 0 и отключить маски глубины и цвета

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

  3. Установите трафарет с 1 для сплошной сетки

  4. Очистить трафарет с 0 для сеток с отверстиями
  5. Включить маски глубины и цвета и отобразить сплошную сетку с трафаретом 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 пластин имеет видс этим):

example

Этот подход больше подходит для тонких объектов.Если ваши порезы приводят к достаточно толстым сторонам, вам нужно добавить рендеринг срезанной стороны, иначе освещение на этих деталях может быть неправильным.

1 голос
/ 19 октября 2010

Я реализовал операции CSG с использованием скалярных полей ранее в этом году. Это работает хорошо, если производительность не важна. То есть расчеты не в реальном времени. Проблема в том, что производная не везде определена, так что вы можете забыть о вычислении дешевых нормалей вершин таким образом. Это должно быть сделано как пост-шаг. Смотрите здесь для бумаги, которую я использовал (в первом ответе), и некоторые скриншоты, которые я сделал:

Операции CSG на неявных поверхностях с движущимися кубами

Кроме того, CSG таким образом требует, чтобы начальная сетка была представлена ​​неявными поверхностями. Хотя любую геометрическую сетку можно разбить на плоскости, она не даст хороших результатов. Таким образом, сферы должны быть представлены радиусом и началом координат, а цилиндры - радиусом, началом координат и высотой основания.

...