PDA

View Full Version : Clipping plane by using stencil buffer for mesh objects with unclosed tubes



michael_ca
08-15-2017, 02:51 PM
:doh:
I have a project, which requires to intersect anatomical mesh objects along specified axis (e.g. from head to foot) into a series of 2D gray-level slices. I used OpenGL stencil buffer with defined clipping plane to generate 2D slices.
For most of mesh objects, I can obtain good 2D intersected slices. But some mesh objects, like heart and trachea, with more tubes not-enclosed (airways, arteries, veins), this clipping algorithm did not work well. After stacking 2D slices to a volume, it looks to be extended along the end of tube to the bottom. Fig. 1 is the mesh object with texturing, Fig.2 shows each slice and Fig. 3 the stacked volume.

Please help find possible reasons for this issue, and any helpful suggestions are welcome.

2450 2453 2451

The following is my code snippets,


GLdouble eq[] = {A, B, C, D};
glClipPlane(GL_CLIP_PLANE0, eq);

glDisable(GL_DEPTH_TEST);
glEnable(GL_CLIP_PLANE0);
glEnable(GL_STENCIL_TEST);

glClear(GL_STENCIL_BUFFER_BIT);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);

// first pass: back face increment
glStencilFunc(GL_ALWAYS, 0, 0);
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
glCullFace(GL_FRONT);
glEnable(GL_CULL_FACE);

DrawCore(false, false, false, false); // draw mesh objects

// second pass: front face increment
glStencilOp(GL_KEEP, GL_KEEP, GL_DECR);
glCullFace(GL_BACK);
glEnable(GL_CULL_FACE);

DrawCore(false, false, false, false); // draw mesh objects

// drawing clip planes masked by stencil buffer content
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glEnable(GL_DEPTH_TEST);
glDisable(GL_CLIP_PLANE0);

glStencilFunc(GL_NOTEQUAL, 0, ~0);

// rendering clip edges to frame buffer
glPushMatrix();
glLoadMatrixf(view_mat); // Clip plane had been set up after view_mat space, thus we need to load
// view_mat matrix before rendering clip plane
glBegin(GL_QUADS);
CVector nrml = cross(CVector(verts[m_nEquationSelection][2] - verts[m_nEquationSelection][1]), CVector(verts[m_nEquationSelection][1] - verts[m_nEquationSelection][0]));
nrml.normalize();
glNormal3f(nrml(0), nrml(1), nrml(2)); //We want plane to be lit properly, thus we need to specify it's normal.

glVertex3f(verts[m_nEquationSelection][0](0) * 100.0, verts[m_nEquationSelection][0](1) - eq[3], verts[m_nEquationSelection][0](2) * 100.0);
glVertex3f(verts[m_nEquationSelection][1](0) * 100.0, verts[m_nEquationSelection][1](1) - eq[3], verts[m_nEquationSelection][1](2) * 100.0);
glVertex3f(verts[m_nEquationSelection][2](0) * 100.0, verts[m_nEquationSelection][2](1) - eq[3], verts[m_nEquationSelection][2](2) * 100.0);
glVertex3f(verts[m_nEquationSelection][3](0) * 100.0, verts[m_nEquationSelection][3](1) - eq[3], verts[m_nEquationSelection][3](2) * 100.0);

glEnd();

glPopMatrix();

saveStencilBufferToExtraMemory(…, …); // using "glReadPixels()" to read the stencil buffer and save to memory and then to a file

glDisable(GL_DEPTH_TEST);

glDisable(GL_STENCIL_TEST);
glClear(GL_STENCIL_BUFFER_BIT);