PDA

View Full Version : how can i translate a clipping plane using keyboard in opengl?



wishi riz
09-15-2015, 03:48 AM
I want to clip a 3D model from head to toe after every 20 mm, start the clipping from head on the z-axis, i have 5 clipping planes right now, when i press 1 the portion above the head part gets clipped off, pressing 2 clips the portion above neck, pressing 3 clips the body portion above chest. The distance between these clipping planes is large right now, the distance should be 20 mm. Creating a huge number of clipping planes in this way is that really possible? i was wondering if i create only one clipping plane and then by pressing the down arrow key translate that clipping plane with a distance of 0.02 m on negative z-axis and pressing the up arrow key moves the clipping plane on positive z-axis. Is that really possible? If yes how to do that , i would be really thank full for all the help.

Here is my code for clipping planes



// toggle each of clipping planes
GLboolean g_clip1 = GL_FALSE;
GLboolean g_clip2 = GL_FALSE;
GLboolean g_clip3 = GL_FALSE;
GLboolean g_clip4 = GL_FALSE;
GLboolean g_clip5 = GL_FALSE;


// clipping planes
GLdouble eqn1[4] = { 0.0, 0.0, -1.0, 0.0 }; //head clip
GLdouble eqn2[4] = { 0.0, 0.0, -1.0, 0.0 }; //face clip
GLdouble eqn3[4] = { 0.0, 0.0, -1.0, 0.0 };// chest clip
GLdouble eqn4[4] = { 0.0, 0.0, -1.0, 0.0 };// abdomen clip
GLdouble eqn5[4] = { 0.0, 0.0, -1.0, 0.0 };// legs clip


// translation for the clipping planes
GLfloat g_clip_1 = 0.47f;
GLfloat g_clip_2 = 0.27f;
GLfloat g_clip_3 = 0.07f;
GLfloat g_clip_4 = -0.13f;
GLfloat g_clip_5 = -0.33f;


// set up the clipping planes
glPushMatrix( );
glTranslatef( 0.0f, 0.0f, g_clip_1 );
glClipPlane( GL_CLIP_PLANE0, eqn1 );
glPopMatrix( );

glPushMatrix( );
glTranslatef( 0.0f, 0.0f, g_clip_2);
glClipPlane( GL_CLIP_PLANE1, eqn2 );
glPopMatrix( );

glPushMatrix( );
glTranslatef( 0.0f, 0.0f, g_clip_3);
glClipPlane( GL_CLIP_PLANE2, eqn3 );
glPopMatrix( );

glPushMatrix( );
glTranslatef( 0.0f, 0.0f, g_clip_4 );
glClipPlane( GL_CLIP_PLANE3, eqn4 );
glPopMatrix( );

glPushMatrix( );
glTranslatef( 0.0f, 0.0f, g_clip_5 );
glClipPlane( GL_CLIP_PLANE4, eqn5 );
glPopMatrix( );


// enable each clipping plane
if( g_clip1 )
glEnable( GL_CLIP_PLANE0 );
else
glDisable( GL_CLIP_PLANE0 );

if( g_clip2 )
glEnable( GL_CLIP_PLANE1 );
else
glDisable( GL_CLIP_PLANE1 );

if( g_clip3 )
glEnable( GL_CLIP_PLANE2 );
else
glDisable( GL_CLIP_PLANE2 );

if( g_clip4 )
glEnable( GL_CLIP_PLANE3 );
else
glDisable( GL_CLIP_PLANE3 );

if( g_clip5 )
glEnable( GL_CLIP_PLANE4 );
else
glDisable( GL_CLIP_PLANE4 );



void keyboard ( unsigned char key, int x, int y )
{
switch ( key )
{
case KEY_ESCAPE:
exit ( 0 );
break;

// toggle the clipping planes

case '1':
g_clip1 = !g_clip1;
break;

case '2':
g_clip2 = !g_clip2;
break;

case '3':
g_clip3 = !g_clip3;
break;

case '4':
g_clip4 = !g_clip4;
break;

case '5':
g_clip5 = !g_clip5;
break;

default:
break;
}
}

Carmine
09-15-2015, 06:46 PM
Something similar to the code below should do.
You only need one clip plane. You do not need any booleans.
You do not need any glTranslate commands.
All you have to do is change one of the values in 'eqn'.



// Put line below in code where 'keyboard' function is defined.
// It assigns functions to the up and down arrow keys.

glutSpecialFunc (Special);

// ----------------------------------------------------------------------------------
// You only need one clip plane as defined below.
// eqn and clip can be global variables.

GLdouble eqn[4] = {0.0, 0.0, 0.47, 0.0};
float clip[5] = {0.47, 0.27, 0.07, -0.13, -0.33};

glEnable (GL_CLIP_PLANE0);
glClipPlane (GL_CLIP_PLANE0, eqn);

// ----------------------------------------------------------------------------------
// Something like the code below is all that is needed to alter the clip plane.

void Special (int key, int x, int y)
{
static int i = 0;

switch (key) {
case GLUT_KEY_UP : i = (++i) % 5; break;
case GLUT_KEY_DOWN : i = (--i) % 5; break;
}

eqn[2] = clip[i];
}

// ----------------------------------------------------------------------------------

void keyboard (unsigned char key, int x, int y )
{
switch (key) {
case KEY_ESCAPE: exit (0); break;
}
}

wishi riz
09-16-2015, 01:42 AM
Thank you for your help :) the code is working, but not the way it should be. When the code runs half of the body which is above origin gets clipped off, and pressing up and down arrow keys clips half of the body above the origin and then the half below the origin ,i don't understand how to fix it. Which parameters should i change so that when i run the code clip plane remains at the 0.4 position on z-axis, and then by pressing the down arrow key it moves down to 0 and then the negative z-axis, and by pressing the up arrow key moves in the positive z-axis?

Carmine
09-16-2015, 10:03 AM
There are a few things you could check.

Is the model displayed correctly (i.e. not clipped at all) if you disable CLIP_PLANE_0?
If not, then you are getting clipping from the near or far clipping planes of the viewing volume.

How does the model when look you load the program without pushing any keys?
If you coded it up the way I suggested, it should be getting clipped at z = 0.47.
Is that happening? If not, again it sounds like your model is not positioned/sized
correctly to fit into the view volume.

wishi riz
09-16-2015, 11:08 AM
Hi!
The model is displayed correctly after disabling the clip plane.
When i load the program i have to press a key to display the model from top view, i have set two views , a top view and a right view. I have set two keys to toggle between these two views.
The clip planes i used worked well with the translations 0.47 0.2 ... that means the model is positioned and sized well, am i right?
The model is placed along z-axis, like a human standing along z-axis, height increases along +z-axis.
After disabling the clip plane pressing the up and down arrow keys have no effect.

GClements
09-17-2015, 12:56 AM
GLdouble eqn[4] = {0.0, 0.0, 0.47, 0.0};



eqn[2] = clip[i];


This is wrong. The first three elements of the plane are the normal vector, the fourth is the distance from the origin.

This code will either clip everything above the origin or everything below the origin depending upon whether eqn[2] is positive or negative. As the fourth element is fixed at zero, the clip plane will always pass through the origin.

To have a plane which is perpendicular to the Z axis and moves along the Z axis, the first three components should be (0,0,1) or (0,0,-1) (depending upon which side you want clipped) and the last component should be the varying offset.

Also:




case GLUT_KEY_UP : i = (++i) % 5; break;
case GLUT_KEY_DOWN : i = (--i) % 5; break;


This isn't valid C; as both the ++/-- and = operators modify i, and modifying a variable more than once without an intervening sequence point results in undefined behaviour. Either use ++/-- or =, but not both in the same expression, i.e. either


case GLUT_KEY_UP : i = (i + 1) % 5; break;
case GLUT_KEY_DOWN : i = (i - 1 + 5) % 5; break;

or:


case GLUT_KEY_UP : i++; i %= 5; break;
case GLUT_KEY_DOWN : i--; i += 5; i %= 5; break;

Note that the "down" version needs to add 5 because the result of C's % operator has the sign of the dividend, not of the divisor, so (-1 % 5) is -1, not 4.

wishi riz
09-17-2015, 02:04 AM
Thank you!
Fixing the elements of eqn[4] has placed the clipping plane on right place, but the plane is still not moving correctly along z-axis. The up and down arrow keys both are giving similar results using this:



case GLUT_KEY_UP : i++; i %= 5; break;
case GLUT_KEY_DOWN : i--; i += 5; i %= 5; break;

Either press up arrow key or down arrow key it moves only once and moves in the same direction. I think after pressing the up or down arrow key the plane disappears because then the program shows full model, and arrow keys have no effect on it.

Carmine
09-17-2015, 10:12 AM
First, try putting the 5 values in the 'clip' array into eqn[3] manually,
one at a time. Don't touch the arrow keys. Do you get the results you expected?
If not, your problem has nothing to do with arrow keys. It's related to the
size of your model and the location of the clip planes defined in your viewing
projection. If you do get the results you expected, then try the block of code
below. It's similar to what I posted before with a few 'corrections'. The
print statement is to make sure the correct value is going into eqn[3].


// ------------------------------------------------------------------

GLdouble eqn[4] = {0.0, 0.0, 1.0, 0.47}; <---
float clip[5] = {0.47, 0.27, 0.07, -0.13, -0.33};

glEnable (GL_CLIP_PLANE0);
glClipPlane (GL_CLIP_PLANE0, eqn);

// -------------------------------------------------------------------

void Special (int key, int x, int y)
{
static int i = 0;

switch (key) {
case GLUT_KEY_UP : i = (i + 1 ) % 5; break; <---
case GLUT_KEY_DOWN : i = (i - 1 + 5) % 5; break; <---
}

eqn[3] = clip[i]; <---
printf (" eqn[3] = %6.2f\n", eqn[3]); <---
}

wishi riz
09-18-2015, 12:07 AM
Thank you so much the program is running exactly the way I wanted. I just changed some values so that I can get the whole model clipped. Thank you once again you guys are really helpful.