non zoomable trihedron

Hi,

I want to show global coordinate frame i.e. at 0,0,0 with x,y and z axes. I am doing this using AIS_Trihedron object but this is zoomable with CAD model. I wanted it look like of same size, like in other CAD tools, when I zoom my model.

Trihedron displayed using V3d_View::TriedronDisplay() is not zoomable but it can not be shown at global coordinate frame location.

Does anybody have solution for this? Any help will be highly appreciated.

TIA,

Ashish

Paul Jimenez's picture

I would also like to know if there is a way to achieve that with OpenCASCADE, but I think it is not possible without patching, probably heavily, the source code.

My not so elegant solution was to create my own trihedron class, and set its size depending on the zooming level (kind of). Thing is, once you zoom in/out, the trihedron will look bigger/smaller.

Another way to do it would be using an over layer. I already did something similar to display a simple 3D arrow pointing to north. The size remains the same all the time, no matter the zooming, panning or rotation. Thing is, you would not get selection through AIS_InteractiveContext (if you need it).

Now that I think of, using NIS could be another way to do it. Too bad NIS is still in so early development.

Ashish's picture

Hello Paul,

Thanks for reply.

Could you share some more information on how you used overlayer to show arrow?

I have been looking in to V3d_View::TriedronDisplay() which gives non-zoomable object but can not be located at given X,Y,Z value. I found that it has its own source file opengl_triedron.c which, i think, does not have view mapping information required for zoom/pan/rotate operation. You can find it in call_triedron_redraw_from_wsid() which is called for every Update() on view. I thought to pass view mapping information to extract right transformation matrix to get correct values of U and V which is passed in call_triedron_redraw(). I have not been successful in this and i fear that i may screw up other functionality.

Could you also tell me what NIS is?

Ashish

Paul Jimenez's picture

I created a class that contains all points to draw the arrow in 3D with a single "stroke" (it is, a sequence of points that defines the arrow (some positions are repeated)). The class can be given a scaling factor and rotation angle to make the arrow point into another direction other than the default one if wanted (gp_Trsf is quite handy here).

The trick now is to use V3d_View::Convert to find where in the view all points of the arrow get projected, then convert those positions to layer positions. Using AddVertex in Polyline mode for the Layer does all the drawing.

Sorry I cannot be of more help, but I cannot publish the code that does that.

Now, about NIS, it is a new package that intends to become as functional as AIS. The main characteristic is that you can use OpenGL directly in your InteractiveObjects to display what you want. It is quite new and far from complete, yet it may become just what we all need.

Ashish's picture

I succeded in making trihedron nonzoomable at global 0,0,0. I have made one more entry in Aspect_TypeOfTriedronPosition as Aspect_TOTP_DYNAMIC.

Then I changed file opengl_triedron.c like this. I skip Opengl transformation for this value i.e. 15. Same thing can be done for z-buffer trihedron

TStatus call_triedron_redraw (
int nz_wks_entry,
int nz_struc_entry,
GLdouble U,
GLdouble V
)
{
GLdouble modelMatrix[4][4];
GLdouble projMatrix[4][4];

GLdouble TriedronAxeX[3] = { 1.0, 0.0, 0.0 };
GLdouble TriedronAxeY[3] = { 0.0, 1.0, 0.0 };
GLdouble TriedronAxeZ[3] = { 0.0, 0.0, 1.0 };
GLdouble TriedronOrigin[3] = { 0.0, 0.0, 0.0 };
GLfloat TriedronColor[3] = { 1.0, 1.0, 1.0 }; /* def = blanc */

/* GLfloat TriedronShade[4] = { 1.0, 1.0, 1.0, 1.0 };*/ /* def = blanc */
/* GLfloat ShadingCoef = 0.5;*/
GLfloat TriedronWidth = 1.0;
GLfloat TriedronScale = (float)0.1 ;
GLint TriedronPosition = 0; /* def = Aspect_TOTP_CENTER */

GLdouble L, l, rayon ;
GLdouble minUV;
int ii;
#ifdef PRINT_MATRIX
int jj;
#endif
int NbFacettes;
double Angle;
GLdouble TriedronCoord[3] = { 1.0, 0.0, 0.0 };

GLuint fontBase;
GLint mode;
char AxeName[2]="X\0";

/*
* Lecture des Init. du Triedre
*/

TriedronColor[0] = nz_wks[nz_wks_entry].nz_struc[nz_struc_entry].aColor[0];
TriedronColor[1] = nz_wks[nz_wks_entry].nz_struc[nz_struc_entry].aColor[1];
TriedronColor[2] = nz_wks[nz_wks_entry].nz_struc[nz_struc_entry].aColor[2];
TriedronScale = nz_wks[nz_wks_entry].nz_struc[nz_struc_entry].aScale;
TriedronPosition = nz_wks[nz_wks_entry].nz_struc[nz_struc_entry].aPos;

/*
* Calcul des axes => on inhibe le zoom.
*/

/* la taille des axes est 1 proportion (fixee a l'init du triedre) */
/* de la dimension la plus petite de la window. */
if ( U < V ) minUV = U;
else minUV = V;
L = minUV * (double) TriedronScale ;

/* Position de l'origine */
TriedronOrigin[0]= 0.0;
TriedronOrigin[1]= 0.0;
TriedronOrigin[2]= 0.0;

/* Position des Axes */
TriedronAxeX[0] = TriedronOrigin[0] + L ;
TriedronAxeX[1] = TriedronOrigin[1] + 0.0;
TriedronAxeX[2] = TriedronOrigin[2] + 0.0;

TriedronAxeY[0] = TriedronOrigin[0] + 0.0;
TriedronAxeY[1] = TriedronOrigin[1] + L ;
TriedronAxeY[2] = TriedronOrigin[2] + 0.0;

TriedronAxeZ[0] = TriedronOrigin[0] + 0.0;
TriedronAxeZ[1] = TriedronOrigin[1] + 0.0;
TriedronAxeZ[2] = TriedronOrigin[2] + L ;

/*
* On inhibe les translations; on conserve les autres transformations.
*/

/* on lit les matrices de transformation et de projection de la vue */
/* pour annuler les translations (dernieres colonnes des matrices). */
glGetDoublev( GL_MODELVIEW_MATRIX, (GLdouble *) modelMatrix );
glGetDoublev( GL_PROJECTION_MATRIX, (GLdouble *) projMatrix );

#ifdef PRINT_MATRIX
printf ("\n--- call_triedron_redraw : avant transfo projMatrix= ");
for (ii = 0; ii<4 ; ii++) {
printf ("\n ");
for (jj = 0; jj<4 ; jj++) {
printf (" %f ", projMatrix[ii][jj] );
}
}
printf ("\n--- call_triedron_redraw : avant transfo modelMatrix= ");
for (ii = 0; ii<4 ; ii++) {
printf ("\n ");
for (jj = 0; jj<4 ; jj++) {
printf (" %f ", modelMatrix[ii][jj] );
}
}
#endif

if(TriedronPosition != 15){
/* on annule la translation qui peut etre affectee a la vue */
modelMatrix[3][0] = 0. ;
modelMatrix[3][1] = 0. ;
modelMatrix[3][2] = 0. ;
projMatrix[3][0] = 0. ;
projMatrix[3][1] = 0. ;
projMatrix[3][2] = 0. ;

/* sauvegarde du contexte des matrices avant chargement */
glMatrixMode (GL_MODELVIEW);
glPushMatrix ();
glLoadIdentity ();
glLoadMatrixd( (GLdouble *) modelMatrix);
glMatrixMode ( GL_PROJECTION );
glPushMatrix ();
glLoadIdentity();
glLoadMatrixd( (GLdouble *) projMatrix);

#ifdef PRINT_MATRIX
printf ("\n\n\n--- call_triedron_redraw : APRES transfo projMatrix= ");
for (ii = 0; ii<4 ; ii++) {
printf ("\n ");
for (jj = 0; jj<4 ; jj++) {
printf (" %f ", projMatrix[ii][jj] );
}
}
printf ("\n--- call_triedron_redraw : APRES transfo modelMatrix= ");
for (ii = 0; ii<4 ; ii++) {
printf ("\n ");
for (jj = 0; jj<4 ; jj++) {
printf (" %f ", modelMatrix[ii][jj] );
}
}
#endif

/*
* Positionnement de l'origine du triedre selon le choix de l'init
*/

/* on fait uniquement une translation de l'origine du Triedre */

switch (TriedronPosition) {

case 0 : /* Aspect_TOTP_CENTER */
break;

case 1 : /* Aspect_TOTP_LEFT_LOWER */
glTranslated( -U/2. + L , -V/2. + L , 0. );
break;

case 2 : /*Aspect_TOTP_LEFT_UPPER */
glTranslated( -U/2. + L , +V/2. - L -L/3. , 0. );
break;

case 3 : /* Aspect_TOTP_RIGHT_LOWER */
glTranslated( U/2. - L -L/3. , -V/2. + L , 0. );
break;

case 4 : /* Aspect_TOTP_RIGHT_UPPER */
glTranslated( U/2. - L -L/3. , +V/2. - L -L/3. , 0. );
break;

default :
break;

}
}

#ifdef PRINT
printf ("\n--- call_triedron_redraw : TriedronOrigin= %f %f %f\n",
TriedronOrigin[0], TriedronOrigin[1], TriedronOrigin[2]);
printf ("\n--- : TriedronAxeX= %f %f %f \n",
TriedronAxeX[0], TriedronAxeX[1], TriedronAxeX[2]);
printf ("\n--- : TriedronAxeY= %f %f %f \n",
TriedronAxeY[0], TriedronAxeY[1], TriedronAxeY[2] );
printf ("\n--- : TriedronAxeZ= %f %f %f \n",
TriedronAxeZ[0], TriedronAxeZ[1], TriedronAxeZ[2]);
printf ("\n--- : TriedronScale= %f \n",TriedronScale);
printf ("\n--- : 1/echelle = ( %f %f %f %f ) \n",
modelMatrix[0][0],modelMatrix[1][1],modelMatrix[2][2],modelMatrix[3][3]);
#endif

/*
* Creation du triedre
*/
glColor3fv (TriedronColor);

#ifdef OCC7667
glGetIntegerv( GL_RENDER_MODE, &mode );

if( mode==GL_RENDER )
glLineWidth( TriedronWidth );
else if( mode==GL_FEEDBACK )
gl2psLineWidth( TriedronWidth );
#else
glLineWidth (TriedronWidth);
#endif

/* dessin des axes */
glBegin(GL_LINES);
glVertex3dv( TriedronOrigin );
glVertex3dv( TriedronAxeX );

glVertex3dv( TriedronOrigin );
glVertex3dv( TriedronAxeY );

glVertex3dv( TriedronOrigin );
glVertex3dv( TriedronAxeZ );
glEnd();

/* fleches au bout des axes (= cones de la couleur demandee) */
l = L - L/4. ; /* distance a l'origine */
rayon = L/30. ; /* rayon de la base du cone */
NbFacettes = 12; /* le cone sera compose de 12 facettes triangulaires */
Angle = 2. * M_PI/ NbFacettes;

/* solution FILAIRE des cones au bout des axes : une seule ligne */
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
/* (la couleur est deja initialisee dans TriedronColor) */
/* FIN de la solution FILAIRE CHOISIE pour les cones des axes */

/* fleche en X */
glBegin(GL_TRIANGLE_FAN);
glVertex3dv( TriedronAxeX );
TriedronCoord[0] = TriedronOrigin[0] + l ;
ii = NbFacettes;
while (ii >= 0 ) {
TriedronCoord[1] = TriedronOrigin[1] + ( rayon * sin(ii * Angle) );
TriedronCoord[2] = TriedronOrigin[2] + ( rayon * cos(ii * Angle) );
glVertex3dv( TriedronCoord );
ii--;
}
glEnd();

/* fleche en Y */
glBegin(GL_TRIANGLE_FAN);
glVertex3dv( TriedronAxeY );
TriedronCoord[1] = TriedronOrigin[1] + l ;
ii = NbFacettes;
while (ii >= 0 ) {
TriedronCoord[0] = TriedronOrigin[0] + (rayon * cos(ii * Angle) );
TriedronCoord[2] = TriedronOrigin[2] + (rayon * sin(ii * Angle) );
glVertex3dv( TriedronCoord );
ii--;
}
glEnd();

/* fleche en Z */
glBegin(GL_TRIANGLE_FAN);
glVertex3dv( TriedronAxeZ );
TriedronCoord[2] = TriedronOrigin[2] + l ;
ii = NbFacettes;
while (ii >= 0 ) {
TriedronCoord[0] = TriedronOrigin[0] + ( rayon * sin(ii * Angle) );
TriedronCoord[1] = TriedronOrigin[1] + ( rayon * cos(ii * Angle) );
glVertex3dv( TriedronCoord );
ii--;
}
glEnd();

/* dessin de l'origine */
TriedronCoord[0] = TriedronOrigin[0] + rayon ;
TriedronCoord[1] = TriedronOrigin[1] + 0.0 ;
TriedronCoord[2] = TriedronOrigin[2] + 0.0 ;
ii = 24 ;
Angle = 2. * M_PI/ii ;
glBegin(GL_LINE_LOOP);
while (ii >= 0 ) {
TriedronCoord[0] = TriedronOrigin[0] + ( rayon * sin(ii * Angle) );
TriedronCoord[1] = TriedronOrigin[1] + ( rayon * cos(ii * Angle) );
glVertex3dv( TriedronCoord );
ii--;
}
glEnd();

LightOff();

/*
* Noms des axes et de l'origine
*/

/* init de la fonte */
#ifndef WNT
fontBase = tXfmsetfont (1.0F, 1.0F);
#else
fontBase = WNTSetFont (1.0F, 1.0F);
#endif /* WNT */

/* Axe X */
strcpy ( AxeName, "X\0" );
TriedronCoord[0] = TriedronOrigin[0] + ( L + rayon ) ;
TriedronCoord[1] = TriedronOrigin[1] + 0.0;
TriedronCoord[2] = TriedronOrigin[2] - rayon ;

#ifndef WNT
tXfmprstr( (unsigned char *) AxeName, fontBase,
(float)TriedronCoord[0], (float)TriedronCoord[1], (float)TriedronCoord[2]);
#else
WNTPuts ( AxeName, fontBase, 0,
(float)TriedronCoord[0], (float)TriedronCoord[1], (float)TriedronCoord[2] );
#endif

/* Axe Y */
strcpy ( AxeName, "Y\0" );
TriedronCoord[0] = TriedronOrigin[0] + rayon ;
TriedronCoord[1] = TriedronOrigin[1] + ( L + 3.0 * rayon ) ;
TriedronCoord[2] = TriedronOrigin[2] + ( 2.0 * rayon );

#ifndef WNT
tXfmprstr( (unsigned char *) AxeName, fontBase, (float)TriedronCoord[0], (float)TriedronCoord[1], (float)TriedronCoord[2]);
#else
WNTPuts ( AxeName, fontBase, 0, (float)TriedronCoord[0], (float)TriedronCoord[1], (float)TriedronCoord[2] );
#endif
/* Axe Z */
strcpy ( AxeName, "Z\0" );
TriedronCoord[0] = TriedronOrigin[0] + ( - 2.0 * rayon ) ;
TriedronCoord[1] = TriedronOrigin[1] + rayon/2. ;
TriedronCoord[2] = TriedronOrigin[2] + ( L + 3.0 * rayon ) ;

#ifndef WNT
tXfmprstr( (unsigned char *) AxeName, fontBase, (float)TriedronCoord[0], (float)TriedronCoord[1], (float)TriedronCoord[2]);
#else
WNTPuts ( AxeName, fontBase, 0,
(float)TriedronCoord[0], (float)TriedronCoord[1], (float)TriedronCoord[2] );
#endif

/*
* restauration du contexte des matrices
*/
if(TriedronPosition!=15){
glMatrixMode (GL_PROJECTION);
glPopMatrix ();
glMatrixMode (GL_MODELVIEW);
glPopMatrix ();
}

return (TSuccess);

}