All of the OpenGL functions and data are encapsulated in a module called GLWin. This module is coded in a style which has the basic characteristics of a standard DevTools module. The files glwin.c and glwin.h are the source and header files for the GLWin module. GLWin is an example of a user written graphics interface module.
This example is implemented using a VglTools interface in file exam1vgl.c.
#include "base/base.h" #include "vgl/vgl.h" #include "vis/vis.h" #include "glwin.h" /* coordinates and data for 8 node hex */ static Vfloat xhex[8][3] = { {0.,0.,0.}, {1.,0.,0.}, {1.,1.,0.}, {0.,1.,0.}, {0.,0.,1.}, {1.,0.,1.}, {1.,1.,1.}, {0.,1.,1.} }; static Vfloat shex[8] = { 0., 1., 1., 0., 1., 2., 2., 1. }; /* coordinates and data (y coordinate) for 20 node tet */ static Vfloat xtet[20][3] = { {0.,0.,0.}, {.5,0.,0.}, {1.,0.,0.}, {1.5,0.,0.}, {0.,.5,0.}, {.5,.5,0.}, {1.,.5,0.}, {0.,1.,0.}, {.5,1.,0.}, {0.,1.5,0.}, {0.,0.,.5}, {.5,0.,.5}, {1.,0.,.5}, {0.,.5,.5}, {.5,.5,.5}, {0.,1.,.5}, {0.,0.,1.}, {.5,0.,1.}, {0.,.5,1.}, {0.,0.,1.5} }; static Vfloat stet[20] = { 0., 0., 0., 0., .5, .5, .5, 1., 1., 1.5, 0., 0., 0., .5, .5, 1., 0., 0., .5, 0. }; static Vfloat rgb[7][3] = { {.2,.2,.2}, {1.,0.,0.}, {0.,1.,0.}, {0.,0.,1.}, {0.,1.,1.}, {1.,0.,1.}, {1.,1.,0.} }; /*---------------------------------------------------------------------- Draw Isosurfaces and Volume Fringes in Hex and Tet ----------------------------------------------------------------------*/ int main() { vgl_DrawFun *df; vis_VisContext *vc; vis_Levels *levels; vis_ColorMap *cmap; vis_TransMap *tmap; vis_Threshold *threshold; GLWin *glwin; int i; Vint nlevels; /* create GL device */ glwin = GLWinBegin (); GLWinCreateWindow (glwin,200,200,400,400); GLWinOrtho (glwin,-2.,2.,-2.,2.,-2.,2.); /* create draw function object for GL */ df = vgl_DrawFunBegin (); GLWinDrawFun (glwin,df); /* vis context and set attributes */ vc = vis_VisContextBegin (); vis_VisContextSetIsoValType (vc,VIS_ISOVALSURFACE); /* levels, set six evenly spaced levels */ levels = vis_LevelsBegin (); nlevels = 6; vis_LevelsDef (levels,LEVELS_LINEAR,nlevels); /* color map */ cmap = vis_ColorMapBegin (); vis_ColorMapSetType (cmap,COLORMAP_TRUECOLOR); vis_ColorMapSetRGB (cmap,nlevels+1,0,rgb); /* create threshold object and set objects */ threshold = vis_ThresholdBegin (); vis_ThresholdSetObject (threshold,VGL_DRAWFUN,df); vis_ThresholdSetObject (threshold,VIS_VISCONTEXT,vc); vis_ThresholdSetObject (threshold,VIS_LEVELS,levels); vis_ThresholdSetObject (threshold,VIS_COLORMAP,cmap); /* draw threshold surfaces */ /* 8 node hex */ vis_LevelsSetMinMax (levels,0.0,2.0); vis_LevelsGenerate (levels,LEVELS_PADENDS); vis_ThresholdSetTopology (threshold,VIS_SHAPEHEX,2,0,0); for(i = 0; i < 10; i++) { GLWinClear (glwin); GLWinXfmPush (glwin); GLWinRotate (glwin,i*12.,'x'); vis_ThresholdCurv (threshold,shex,xhex,VIS_NODATA,NULL); GLWinXfmPop (glwin); GLWinSwap (glwin); sleep(1); } sleep(2); /* 20 node tet */ vis_LevelsSetMinMax (levels,0.0,1.5); vis_LevelsGenerate (levels,LEVELS_PADENDS); vis_ThresholdSetTopology (threshold,VIS_SHAPETET,4,4,4); for(i = 0; i < 10; i++) { GLWinClear (glwin); GLWinXfmPush (glwin); GLWinRotate (glwin,i*12.,'x'); vis_ThresholdCurv (threshold,stet,xtet,VIS_NODATA,NULL); GLWinXfmPop (glwin); GLWinSwap (glwin); sleep(1); } sleep(2); /* transparency map */ tmap = vis_TransMapBegin (); vis_TransMapSetType (tmap,TRANSMAP_FACTOR); vis_TransMapRamp (tmap,nlevels+2,0,TRANSMAP_UP); vis_TransMapSetDecay (tmap,.1); /* set object in threshold */ vis_ThresholdSetObject (threshold,VIS_TRANSMAP,tmap); /* set viscontext for volume fringing */ vis_VisContextSetIsoValType (vc,VIS_ISOVALFRINGE); vis_VisContextSetMapTrans (vc,VIS_ON); vis_VisContextSetSize (vc,.05); /* draw threshold volume fringes */ /* 8 node hex */ vis_LevelsSetMinMax (levels,0.0,2.0); vis_LevelsGenerate (levels,LEVELS_PADENDS); vis_ThresholdSetTopology (threshold,VIS_SHAPEHEX,2,0,0); for(i = 0; i < 10; i++) { GLWinClear (glwin); GLWinXfmPush (glwin); GLWinRotate (glwin,i*12.,'x'); vis_ThresholdCurv (threshold,shex,xhex,VIS_NODATA,NULL); GLWinXfmPop (glwin); GLWinSwap (glwin); sleep(1); } sleep(2); /* 20 node tet */ vis_LevelsSetMinMax (levels,0.0,1.5); vis_LevelsGenerate (levels,LEVELS_PADENDS); vis_ThresholdSetTopology (threshold,VIS_SHAPETET,4,4,4); for(i = 0; i < 10; i++) { GLWinClear (glwin); GLWinXfmPush (glwin); GLWinRotate (glwin,i*12.,'x'); vis_ThresholdCurv (threshold,stet,xtet,VIS_NODATA,NULL); GLWinXfmPop (glwin); GLWinSwap (glwin); sleep(1); } sleep(2); /* free all objects */ vgl_DrawFunEnd (df); vis_VisContextEnd (vc); vis_LevelsEnd (levels); vis_ColorMapEnd (cmap); vis_TransMapEnd (tmap); vis_ThresholdEnd (threshold); GLWinEnd (glwin); return 0; }
#include "base/base.h" #include "vgl/vgl.h" #include "vis/vis.h" #include "glwin.h" static Vfloat rgb[3][3] = { {0.,0.,0.}, {1.,1.,1.}, {.5,.5,.5} }; static Vfloat xtex[3] = { -3.8, 1.8, 0. }; static Vfloat ctex[3] = { 1., 1., 1. }; /*---------------------------------------------------------------------- Draw legends ----------------------------------------------------------------------*/ int main() { vgl_DrawFun *df; vis_VisContext *vc; vis_ColorMap *cmap; vis_TransMap *tmap; vis_Levels *levels; vis_Legend *legend; GLWin *glwin; Vfloat x[3]; Vint nlevels; /* create GL device */ glwin = GLWinBegin (); GLWinCreateWindow (glwin,200,200,800,400); GLWinOrtho (glwin,-4.,4.,-2.,2.,-2.,2.); /* create draw function object for GL */ df = vgl_DrawFunBegin (); GLWinDrawFun (glwin,df); vc = vis_VisContextBegin (); vis_VisContextSetLineWidth (vc,2); vis_VisContextSetMinorLineStyle (vc,VIS_SOLID); vis_VisContextSetMinorLineWidth (vc,2); vis_VisContextSetMinorColor (vc,14); vis_VisContextSetColor (vc,15); vis_VisContextSetTrans (vc,1); vis_VisContextSetFormat (vc,VIS_E2FORMAT); vis_VisContextSetFrequency (vc,0); vis_VisContextSetMapTrans (vc,VIS_OFF); nlevels = 12; /* color map */ cmap = vis_ColorMapBegin (); vis_ColorMapSetType (cmap,COLORMAP_TRUECOLOR); vis_ColorMapRamp (cmap,nlevels,1,COLORMAP_ANSYS); vis_ColorMapSetRGB (cmap,3,13,rgb); /* transparency map */ tmap = vis_TransMapBegin (); vis_TransMapSetType (tmap,TRANSMAP_FACTOR); vis_TransMapRamp (tmap,nlevels,1,TRANSMAP_UP); /* levels, generate evenly spaced levels */ levels = vis_LevelsBegin (); vis_LevelsDef (levels,LEVELS_LINEAR,nlevels); vis_LevelsSetMinMax (levels,-2.,2.); vis_LevelsSetLabel (levels,nlevels-2," Yield Stress"); /* create Legend object and set objects */ legend = vis_LegendBegin (); vis_LegendSetObject (legend,VGL_DRAWFUN,df); vis_LegendSetObject (legend,VIS_VISCONTEXT,vc); vis_LegendSetObject (legend,VIS_COLORMAP,cmap); vis_LegendSetObject (legend,VIS_TRANSMAP,tmap); vis_LegendSetObject (legend,VIS_LEVELS,levels); /* draw vertical layout */ x[0] = -1.; x[1] = -1.5; x[2] = 0.; vis_VisContextSetSize (vc,.5); vis_VisContextSetMinorSize (vc,3.); vis_LegendSetParami (legend,LEGEND_LAYOUT,LEGEND_VERTICAL); /* Fringe, Accent, Raster Font */ vis_VisContextSetFlags (vc,VIS_ISOVALACCENT); vis_LegendSetParami (legend,LEGEND_STROKEFONT,VIS_OFF); vis_LegendSetParami (legend,LEGEND_SPECTRUM,LEGEND_FRINGE); vis_LegendSetParami (legend,LEGEND_PADTOP,VIS_ON); vis_LegendSetParami (legend,LEGEND_LABELUSELEVELS,VIS_ON); vis_LevelsGenerate (levels,LEVELS_PADTOP); GLWinClear (glwin); GLWinColor (glwin,ctex); GLWinText (glwin,xtex,"Vertical, Fringe, Accent, Raster Font"); vis_LegendDraw (legend,x); GLWinSwap (glwin); sleep(5); /* Now draw labels on left */ vis_LegendSetParami (legend,LEGEND_LABELLEFT,VIS_ON); GLWinClear (glwin); GLWinColor (glwin,ctex); GLWinText (glwin,xtex,"Vertical, Fringe, Accent, Raster Font, Left Labels"); vis_LegendDraw (legend,x); GLWinSwap (glwin); sleep(5); /* Tone, Accent, Stroke Font */ vis_LegendSetParami (legend,LEGEND_LABELLEFT,VIS_OFF); vis_VisContextSetFlags (vc,VIS_OFF); vis_LegendSetParami (legend,LEGEND_STROKEFONT,VIS_ON); vis_LegendSetParami (legend,LEGEND_SPECTRUM,LEGEND_TONE); vis_LegendSetParami (legend,LEGEND_PADTOP,VIS_OFF); vis_LegendSetParami (legend,LEGEND_LABELUSELEVELS,VIS_OFF); vis_LevelsGenerate (levels,LEVELS_PADNONE); GLWinClear (glwin); GLWinColor (glwin,ctex); GLWinText (glwin,xtex,"Vertical, Tone, Accent, Stroke Font"); vis_LegendDraw (legend,x); GLWinSwap (glwin); sleep(5); /* draw horizontal layout */ x[0] = -3.5; x[1] = 0.; x[2] = 0.; vis_VisContextSetSize (vc,7.); vis_VisContextSetMinorSize (vc,.25); vis_LegendSetParami (legend,LEGEND_LAYOUT,LEGEND_HORIZONTAL); /* Line, Border, Stroked Font */ vis_VisContextSetFlags (vc,VIS_OFF); vis_LegendSetParami (legend,LEGEND_BORDER,VIS_ON); vis_LegendSetParami (legend,LEGEND_SPECTRUM,LEGEND_LINE); vis_LegendSetParami (legend,LEGEND_PADTOP,VIS_ON); vis_LegendSetParami (legend,LEGEND_PADBOTTOM,VIS_ON); vis_LevelsGenerate (levels,LEVELS_PADENDS); GLWinClear (glwin); GLWinColor (glwin,ctex); GLWinText (glwin,xtex,"Horizontal, Line, Border, Stroke Font"); vis_LegendDraw (legend,x); GLWinSwap (glwin); sleep(5); /* free all objects */ vgl_DrawFunEnd (df); vis_VisContextEnd (vc); vis_ColorMapEnd (cmap); vis_TransMapEnd (tmap); vis_LevelsEnd (levels); vis_LegendEnd (legend); GLWinEnd (glwin); return 0; }
#include "base/base.h" #include "vgl/vgl.h" #include "vis/vis.h" #include "glwin.h" static Vfloat xhex[8][3] = { {0.,0.,0.}, {1.,0.,0.}, {1.,1.,0.}, {0.,1.,0.}, {0.,0.,1.}, {1.,0.,1.}, {1.,1.,1.}, {0.,1.,1.} }; static Vfloat rgb[7][3] = { {.2,.2,.2}, {1.,.2,.2}, {.2,1.,.2}, {.2,.2,1.}, {0.,1.,1.}, {1.,0.,1.}, {1.,1.,0.} }; /*---------------------------------------------------------------------- Generate vectors at vertices of a hexahedron ----------------------------------------------------------------------*/ int main() { vgl_DrawFun *df; vis_VisContext *vc; vis_Levels *levels; vis_ColorMap *cmap; vis_Mark *mark; GLWin *glwin; int i; Vint nlevels; Vfloat tm[4][4]; /* create GL device */ glwin = GLWinBegin (); GLWinCreateWindow (glwin,200,200,400,400); GLWinOrtho (glwin,-2.,2.,-2.,2.,-2.,2.); /* create draw function object for GL */ df = vgl_DrawFunBegin (); GLWinDrawFun (glwin,df); /* viscontext and set attributes */ vc = vis_VisContextBegin (); vis_VisContextSetFlags (vc,VIS_VECTORTAIL | VIS_VECTORTAILREGISTER); vis_VisContextSetVectorType (vc,VIS_VECTORCYLINDER); vis_VisContextSetSize (vc,.5); /* levels, set six evenly spaced levels */ levels = vis_LevelsBegin (); nlevels = 6; vis_LevelsDef (levels,LEVELS_LINEAR,nlevels); vis_LevelsSetMinMax (levels,0.,2.); vis_LevelsGenerate (levels,LEVELS_PADENDS); /* color map */ cmap = vis_ColorMapBegin (); vis_ColorMapSetType (cmap,COLORMAP_TRUECOLOR); vis_ColorMapSetRGB (cmap,nlevels+1,0,rgb); /* create mark object and set objects */ mark = vis_MarkBegin (); vis_MarkSetObject (mark,VGL_DRAWFUN,df); vis_MarkSetObject (mark,VIS_VISCONTEXT_VECTOR,vc); vis_MarkSetObject (mark,VIS_LEVELS,levels); vis_MarkSetObject (mark,VIS_COLORMAP,cmap); /* draw vectors */ for(i = 0; i < 15; i++) { GLWinClear (glwin); GLWinXfmPush (glwin); GLWinRotate (glwin,i*12.,'x'); vis_MarkVector (mark,8,xhex,xhex); GLWinXfmPop (glwin); GLWinSwap (glwin); sleep(1); } sleep(5); /* draw viewplane projected vectors */ vis_VisContextSetProject (vc,VIS_ON); vis_VisContextSetVectorType (vc,VIS_VECTORLINE); vis_VisContextSetFill (vc,VIS_OFF); vis_VisContextSetFlags (vc,VIS_VECTORTAIL | VIS_VECTORTAILREGISTER | VIS_VECTORNOCAP); for(i = 0; i < 15; i++) { GLWinClear (glwin); GLWinXfmPush (glwin); GLWinRotate (glwin,i*12.,'x'); /* get the current modelview matrix */ GLWinXfmGet (glwin,tm); /* set matrix in viscontext */ vis_VisContextSetXfmMatrix (vc,tm); /* draw vectors */ vis_MarkVector (mark,8,xhex,xhex); GLWinXfmPop (glwin); GLWinSwap (glwin); sleep(1); } sleep(5); /* free all objects */ vgl_DrawFunEnd (df); vis_VisContextEnd (vc); vis_LevelsEnd (levels); vis_ColorMapEnd (cmap); vis_MarkEnd (mark); GLWinEnd (glwin); return 0; }
#include "base/base.h" #include "vis/vis.h" /* sample tensor */ static Vdouble td[6] = { 5.2586293220520020, 0.32901409268379211, -0.18742503225803375, 0.23982234299182892, -0.042775686830282211, 0.76196306943893433 }; /*---------------------------------------------------------------------- Tensor Computations Using Mark ----------------------------------------------------------------------*/ int main() { vis_Mark *mark; int i, j; Vfloat ts[6]; Vfloat vs[6], tms[3][3]; Vdouble vd[6], tmd[3][3]; /* create mark object */ mark = vis_MarkBegin (); /* load double precison tensor into single */ for(i = 0; i < 6; i++) { ts[i] = td[i]; } /* compute principal values in single, double precision */ vis_MarkTensorPrincipal (mark,ts,vs,tms); printf("Single precision\n"); printf("Principal values\n"); for(i = 0; i < 3; i++) { printf(" %e\n",vs[i]); } printf("Principal directions\n"); for(i = 0; i < 3; i++) { for(j = 0; j < 3; j++) { printf(" %16.9e",tms[i][j]); } printf("\n"); } vis_MarkTensorPrincipaldv (mark,td,vd,tmd); printf("Double precision\n"); printf("Principal values\n"); for(i = 0; i < 3; i++) { printf(" %e\n",vd[i]); } printf("Principal directions\n"); for(i = 0; i < 3; i++) { for(j = 0; j < 3; j++) { printf(" %16.9e",tmd[i][j]); } printf("\n"); } /* compute max shear values in single, double precision */ vis_MarkTensorMaxShear (mark,ts,vs,tms); printf("Single precision\n"); printf("Max Shear values\n"); for(i = 0; i < 6; i++) { printf(" %e\n",vs[i]); } printf("Max Shear directions\n"); for(i = 0; i < 3; i++) { for(j = 0; j < 3; j++) { printf(" %16.9e",tms[i][j]); } printf("\n"); } vis_MarkTensorMaxSheardv (mark,td,vd,tmd); printf("Double precision\n"); printf("Max Shear values\n"); for(i = 0; i < 6; i++) { printf(" %e\n",vd[i]); } printf("Max Shear directions\n"); for(i = 0; i < 3; i++) { for(j = 0; j < 3; j++) { printf(" %16.9e",tmd[i][j]); } printf("\n"); } vis_MarkEnd (mark); return 0; }
#include "base/base.h" #include "vgl/vgl.h" #include "vis/vis.h" #include "glwin.h" static Vfloat xhex[8][3] = { {0.,0.,0.}, {1.,0.,0.}, {1.,1.,0.}, {0.,1.,0.}, {0.,0.,1.}, {1.,0.,1.}, {1.,1.,1.}, {0.,1.,1.} }; static Vfloat shex[8] = { 0., 1., 1., 0., 1., 2., 2., 1. }; static Vfloat rhex[8] = { 0., 0., 1., 1., 0., 0., 1., 1. }; static Vfloat rgb[7][3] = { {.2,.2,.2}, {1.,0.,0.}, {0.,1.,0.}, {0.,0.,1.}, {0.,1.,1.}, {1.,0.,1.}, {1.,1.,0.} }; /*---------------------------------------------------------------------- Generate isosurfaces in a hexahedron ----------------------------------------------------------------------*/ int main() { vgl_DrawFun *dfGL, *dfC; vis_VisContext *vc, *vcC; vis_Levels *levels, *levelsC; vis_ColorMap *cmap; vis_Threshold *threshold; vis_Contour *contour; vis_DataInt *dataint; GLWin *glwin; int i; Vint nlevels, nlevelsC; /* create GL device */ glwin = GLWinBegin (); GLWinCreateWindow (glwin,200,200,400,400); GLWinOrtho (glwin,-2.,2.,-2.,2.,-2.,2.); /* create drawing function object for GL */ dfGL = vgl_DrawFunBegin (); GLWinDrawFun (glwin,dfGL); /* Threshold data interpolation */ dataint = vis_DataIntBegin (); vis_DataIntSetDataPtr (dataint,0,1,rhex); /* Threshold vis context and set attributes */ vc = vis_VisContextBegin (); vis_VisContextSetIsoValType (vc,VIS_ISOVALSURFACE); vis_VisContextSetDraw (vc,VIS_OFF); vis_VisContextSetShade (vc,VIS_NOSHADE); /* Threshold levels, set three evenly spaced levels */ levels = vis_LevelsBegin (); nlevels = 3; vis_LevelsDef (levels,LEVELS_LINEAR,nlevels); vis_LevelsSetMinMax (levels,0.,2.); vis_LevelsGenerate (levels,LEVELS_PADENDS); /* Contour vis context and set attributes */ vcC = vis_VisContextBegin (); vis_VisContextSetIsoValType (vcC,VIS_ISOVALFRINGE); /* Contour levels, set six evenly spaced levels */ levelsC = vis_LevelsBegin (); nlevelsC = 6; vis_LevelsDef (levelsC,LEVELS_LINEAR,nlevelsC); vis_LevelsSetMinMax (levelsC,0.,1.); vis_LevelsGenerate (levelsC,LEVELS_PADTOP); /* color map */ cmap = vis_ColorMapBegin (); vis_ColorMapSetType (cmap,COLORMAP_TRUECOLOR); vis_ColorMapSetRGB (cmap,nlevelsC+1,0,rgb); /* create contour object and set objects */ contour = vis_ContourBegin (); vis_ContourSetObject (contour,VGL_DRAWFUN,dfGL); vis_ContourSetObject (contour,VIS_VISCONTEXT,vcC); vis_ContourSetObject (contour,VIS_LEVELS,levelsC); vis_ContourSetObject (contour,VIS_COLORMAP,cmap); /* create contouring drawing function object */ dfC = vgl_DrawFunBegin (); vgl_DrawFunSetObj (dfC,contour); vgl_DrawFunAPI (dfC,DRAWFUN_APIRETURN); /* use function provided by Contour module */ vgl_DrawFunSet (dfC,DRAWFUN_POLYGONDATA,(Vfunc*)vis_ContourPolygonData); /* create threshold object and set objects */ threshold = vis_ThresholdBegin (); vis_ThresholdSetObject (threshold,VGL_DRAWFUN,dfC); vis_ThresholdSetObject (threshold,VIS_VISCONTEXT,vc); vis_ThresholdSetObject (threshold,VIS_LEVELS,levels); vis_ThresholdSetObject (threshold,VIS_DATAINT,dataint); /* draw threshold surfaces */ for(i = 0; i < 30; i++) { GLWinClear (glwin); GLWinXfmPush (glwin); GLWinRotate (glwin,i*12.,'x'); vis_ThresholdCurv (threshold,shex,xhex,VIS_NODATA,NULL); GLWinXfmPop (glwin); GLWinSwap (glwin); sleep(1); } sleep(5); /* free all objects */ vgl_DrawFunEnd (dfGL); vgl_DrawFunEnd (dfC); vis_VisContextEnd (vc); vis_VisContextEnd (vcC); vis_LevelsEnd (levels); vis_LevelsEnd (levelsC); vis_ColorMapEnd (cmap); vis_ThresholdEnd (threshold); vis_ContourEnd (contour); vis_DataIntEnd (dataint); GLWinEnd (glwin); return 0; }
The basic concept is to place the Threshold and Contour objects into the data interpolation mode using DataInt attribute objects. The Threshold object interpolates the scalar data field and global x coordinate while extracting an isosurface at y = .4 from a scalar field of the y coordinates. The output from the Threshold object is now directed to a new DrawFun object which contains the custom drawing function, TPolygonData, which calls a Contour object for performing the next step in the process. The Contour object interpolates the scalar data field while extracting an isoline at x = .2 from a scalar field of the x coordinates. The output from the Contour object is directed to the vis_SegmentPolyLineData function which draws fringes of the interpolated scalar data field on the line which forms the intersection of the x = .4 and y = .2 planes.
A custom structure, Tobj, is defined to facilitate passing the Contour object and the associated data pointer together to the TPolygonData function.
In this example the isoline is the intersection of two planes in global coordinates, but in general any two isosurfaces may be used. For example, to fringe a scalar data field on an arbitrarily oriented straight line, fill dthex[i][1] and sthex with coordinates rotated to a coordinate system aligned to the straight line and extract isovalues at the desired constant values in the rotated coordinate system.
#include "base/base.h" #include "vgl/vgl.h" #include "vis/vis.h" #include "glwin.h" static Vfloat xhex[8][3] = { {0.,0.,0.}, {1.,0.,0.}, {1.,1.,0.}, {0.,1.,0.}, {0.,0.,1.}, {1.,0.,1.}, {1.,1.,1.}, {0.,1.,1.} }; static Vfloat shex[8] = { 0., 1., 1., 0., 1., 2., 2., 1. }; static Vfloat rgb[7][3] = { {.2,.2,.2}, {1.,0.,0.}, {0.,1.,0.}, {0.,0.,1.}, {0.,1.,1.}, {1.,0.,1.}, {1.,1.,0.} }; typedef struct Tobj { vis_Contour *contour; Vfloat *dctri; } Tobj; /*---------------------------------------------------------------------- Drawing function for output from Threshold ----------------------------------------------------------------------*/ static void TPolygonData(Vobject *obj, Vint type, Vint npts, Vfloat x[][3], Vint nrws, Vfloat *d, Vint vflag, Vfloat v[]) { int i; Vfloat sctri[3]; Tobj *tobj; tobj = (Tobj*)obj; /* fill dctri with scalar */ /* fill sctri with x coordinate */ for(i = 0; i < 3; i++) { tobj->dctri[i] = d[nrws*i]; sctri[i] = d[nrws*i+1]; } if(npts == 3) { vis_ContourSetTopology (tobj->contour,VIS_SHAPETRI,0,0); } else { vis_ContourSetTopology (tobj->contour,VIS_SHAPEQUAD,0,0); } vis_ContourCurv (tobj->contour,sctri,x,VIS_NODATA,NULL); } /*---------------------------------------------------------------------- Generate isolines in a hexahedron ----------------------------------------------------------------------*/ int main() { vgl_DrawFun *dfGL, *dfT, *dfC; vis_DataInt *diT, *diC; vis_VisContext *vcT, *vcC, *vc; vis_Levels *levelsT, *levelsC, *levels; vis_ColorMap *cmap; vis_Threshold *threshold; vis_Segment *segment; GLWin *glwin; int i; Vint nlevels; Vfloat dthex[8][2], sthex[8]; /* object info for Threshold drawing function */ Tobj tobj; vis_Contour *contour; Vfloat dctri[3]; /* create GL device */ glwin = GLWinBegin (); GLWinCreateWindow (glwin,200,200,400,400); GLWinOrtho (glwin,-2.,2.,-2.,2.,-2.,2.); /* create drawing function object for GL */ dfGL = vgl_DrawFunBegin (); GLWinDrawFun (glwin,dfGL); /* Threshold levels, set one level at .2 */ levelsT = vis_LevelsBegin (); vis_LevelsDef (levelsT,LEVELS_LINEAR,1); vis_LevelsSetValue (levelsT,1,.2); /* Contour levels, set one level at .4 */ levelsC = vis_LevelsBegin (); vis_LevelsDef (levelsC,LEVELS_LINEAR,1); vis_LevelsSetValue (levelsC,1,.4); /* Segment levels, set six evenly spaced levels */ levels = vis_LevelsBegin (); nlevels = 6; vis_LevelsDef (levels,LEVELS_LINEAR,nlevels); vis_LevelsSetMinMax (levels,0.,2.); vis_LevelsGenerate (levels,LEVELS_PADTOP); /* color map */ cmap = vis_ColorMapBegin (); vis_ColorMapSetType (cmap,COLORMAP_TRUECOLOR); vis_ColorMapSetRGB (cmap,nlevels+1,0,rgb); /* Segment vis context and set attributes */ vc = vis_VisContextBegin (); vis_VisContextSetIsoValType (vc,VIS_ISOVALFRINGE); vis_VisContextSetLineWidth (vc,2); /* create segment object and set objects */ segment = vis_SegmentBegin (); vis_SegmentSetObject (segment,VGL_DRAWFUN,dfGL); vis_SegmentSetObject (segment,VIS_VISCONTEXT,vc); vis_SegmentSetObject (segment,VIS_LEVELS,levels); vis_SegmentSetObject (segment,VIS_COLORMAP,cmap); /* Contour vis context and set attributes */ vcC = vis_VisContextBegin (); vis_VisContextSetIsoValType (vcC,VIS_ISOVALLINE); vis_VisContextSetDraw (vcC,VIS_OFF); vis_VisContextSetShade (vcC,VIS_NOSHADE); vis_VisContextSetMapColor (vcC,VIS_OFF); /* create drawing function object for Contour output*/ dfC = vgl_DrawFunBegin (); vgl_DrawFunSetObj (dfC,segment); vgl_DrawFunAPI (dfC,DRAWFUN_APIRETURN); /* use function provided by Segment module */ vgl_DrawFunSet (dfC,DRAWFUN_POLYLINEDATA,(Vfunc*)vis_SegmentPolyLineData); /* Contour data interpolation */ diC = vis_DataIntBegin (); vis_DataIntSetDataPtr (diC,0,1,(Vfloat*)dctri); /* create contour object and set objects */ contour = vis_ContourBegin (); vis_ContourSetObject (contour,VGL_DRAWFUN,dfC); vis_ContourSetObject (contour,VIS_VISCONTEXT,vcC); vis_ContourSetObject (contour,VIS_LEVELS,levelsC); vis_ContourSetObject (contour,VIS_DATAINT,diC); /* Threshold vis context and set attributes */ vcT = vis_VisContextBegin (); vis_VisContextSetIsoValType (vcT,VIS_ISOVALSURFACE); vis_VisContextSetDraw (vcT,VIS_OFF); vis_VisContextSetShade (vcT,VIS_NOSHADE); vis_VisContextSetMapColor (vcT,VIS_OFF); /* fill object info */ tobj.contour = contour; tobj.dctri = dctri; /* create drawing function object for Threshold output*/ dfT = vgl_DrawFunBegin (); vgl_DrawFunSetObj (dfT,(Vobject*)&tobj); vgl_DrawFunAPI (dfT,DRAWFUN_APIRETURN); vgl_DrawFunSet (dfT,DRAWFUN_POLYGONDATA,(Vfunc*)TPolygonData); /* Threshold data interpolation */ diT = vis_DataIntBegin (); vis_DataIntSetDataPtr (diT,0,2,(Vfloat*)dthex); /* create threshold object and set objects */ threshold = vis_ThresholdBegin (); vis_ThresholdSetObject (threshold,VGL_DRAWFUN,dfT); vis_ThresholdSetObject (threshold,VIS_VISCONTEXT,vcT); vis_ThresholdSetObject (threshold,VIS_LEVELS,levelsT); vis_ThresholdSetObject (threshold,VIS_DATAINT,diT); /* fill dthex with scalar and x coordinate */ /* fill sthex with y coordinate */ for(i = 0; i < 8; i++) { dthex[i][0] = shex[i]; dthex[i][1] = xhex[i][0]; sthex[i] = xhex[i][1]; } /* draw segments */ for(i = 0; i < 30; i++) { GLWinClear (glwin); GLWinXfmPush (glwin); GLWinRotate (glwin,i*12.,'x'); vis_ThresholdCurv (threshold,sthex,xhex,VIS_NODATA,NULL); GLWinXfmPop (glwin); GLWinSwap (glwin); sleep(1); } sleep(5); /* free all objects */ vgl_DrawFunEnd (dfGL); vgl_DrawFunEnd (dfT); vgl_DrawFunEnd (dfC); vis_DataIntEnd (diT); vis_DataIntEnd (diC); vis_VisContextEnd (vcT); vis_VisContextEnd (vcC); vis_VisContextEnd (vc); vis_LevelsEnd (levelsT); vis_LevelsEnd (levelsC); vis_LevelsEnd (levels); vis_ColorMapEnd (cmap); vis_ThresholdEnd (threshold); vis_ContourEnd (contour); vis_SegmentEnd (segment); GLWinEnd (glwin); return 0; }
A data structure critical to generating tangent curves is the element adjacency array, adj in this example. The adjacency array contains the element numbers adjacent to each element across each element edge. A zero flags a free edge. This information is used to propagate the tangent curve from one element to its neighbor.
This example is implemented using a VglTools interface in file exam5vgl.c.
#include "base/base.h" #include "vgl/vgl.h" #include "vis/vis.h" #include "glwin.h" static void gather(Vfloat x[][3], Vint con[4], Vfloat xe[][3]); static Vfloat xquad[9][3] = { {0.,0.,0.}, {1.,0.,0.}, {2.,0.,0.}, {0.,1.,0.}, {1.,1.,0.}, {2.,1.,0.}, {0.,2.,0.}, {1.,2.,0.}, {2.,2.,0.} }; static Vfloat vquad[9][3] = { {1.,0.,0.}, {1.,0.,0.}, {1.,1.,0.}, {0.,0.,0.}, {0.,0.,0.}, {0.,1.,0.}, {-1.,0.,0.}, {-1.,0.,0.},{-1.,1.,0.} }; static Vint con[4][4] = { {1,2,5,4}, {2,3,6,5}, {4,5,8,7}, {5,6,9,8} }; static Vint adj[4][4] = { {0,2,3,0}, {0,0,4,1}, {1,4,0,0}, {2,0,0,3} }; static Vfloat rgb[7][3] = { {.2,.2,.2}, {1.,0.,0.}, {0.,1.,0.}, {0.,0.,1.}, {0.,1.,1.}, {1.,0.,1.}, {1.,1.,0.} }; /*---------------------------------------------------------------------- Generate tangent curve on quadrilateral elements ----------------------------------------------------------------------*/ int main() { vgl_DrawFun *df; vis_VisContext *vcface, *vcmark, *vctrace; vis_ColorMap *cmap; vis_Face *face; vis_Mark *mark; vis_Trace *trace; GLWin *glwin; int i, j; Vfloat xe[4][3], ve[4][3], xc[3]; Vint nn; Vfloat t; Vint status, edgenumber; Vfloat tout; Vfloat v[3], w[3], vout[3], wout[3]; /* create GL device */ glwin = GLWinBegin (); GLWinCreateWindow (glwin,100,100,600,600); GLWinOrtho (glwin,-1.,3.,-1.,3.,-3.,3.); /* create drawing function object for GL */ df = vgl_DrawFunBegin (); GLWinDrawFun (glwin,df); /* vis context and set attributes */ vcface = vis_VisContextBegin (); vis_VisContextSetEdge (vcface,VIS_ON); vis_VisContextSetFill (vcface,VIS_OFF); vis_VisContextSetColor (vcface,4); vcmark = vis_VisContextBegin (); vis_VisContextSetFlags (vcmark,VIS_VECTORTAIL | VIS_VECTORTAILREGISTER); vis_VisContextSetVectorType (vcmark,VIS_VECTORCYLINDER); vis_VisContextSetSize (vcmark,.5); vis_VisContextSetMapColor (vcmark,VIS_OFF); vis_VisContextSetColor (vcmark,1); vctrace = vis_VisContextBegin (); vis_VisContextSetLineStyle (vctrace,VIS_CYLINDER); vis_VisContextSetSize (vctrace,.25); vis_VisContextSetColor (vctrace,6); /* color map */ cmap = vis_ColorMapBegin (); vis_ColorMapSetType (cmap,COLORMAP_TRUECOLOR); vis_ColorMapSetRGB (cmap,7,0,rgb); /* create face object and set objects */ face = vis_FaceBegin (); vis_FaceSetObject (face,VGL_DRAWFUN,df); vis_FaceSetObject (face,VIS_VISCONTEXT,vcface); vis_FaceSetObject (face,VIS_COLORMAP,cmap); /* create mark object and set objects */ mark = vis_MarkBegin (); vis_MarkSetObject (mark,VGL_DRAWFUN,df); vis_MarkSetObject (mark,VIS_VISCONTEXT_VECTOR,vcmark); vis_MarkSetObject (mark,VIS_COLORMAP,cmap); /* create trace object and set objects */ trace = vis_TraceBegin (); vis_TraceSetObject (trace,VGL_DRAWFUN,df); vis_TraceSetObject (trace,VIS_VISCONTEXT,vctrace); vis_TraceSetObject (trace,VIS_COLORMAP,cmap); vis_TraceSetContinuous (trace,VIS_ON); for(i = 0; i < 10; i++) { GLWinClear (glwin); GLWinXfmPush (glwin); GLWinRotate (glwin,i*12.,'x'); /* draw face outlines */ vis_VisContextTouch (vcface); for(j = 0; j < 4; j++) { gather (xquad,con[j],xe); vis_FaceCurv (face,xe,0,NULL); } /* draw vectors */ vis_VisContextTouch (vcmark); vis_MarkVector (mark,9,vquad,xquad); /* draw tangent curve */ vis_VisContextTouch (vctrace); t = 0.; nn = 0; xc[0] = 0.; xc[1] = .5; xc[2] = 0.; v[0] = 0.; v[1] = 0.; v[2] = 0.; w[0] = 0.; w[1] = 0.; w[2] = 0.; for(;;) { gather (xquad,con[nn],xe); gather (vquad,con[nn],ve); vis_TraceSetEnter (trace,SYS_ON,xc,v,w,t); vis_TraceCurv (trace,VIS_VECTOR,(Vfloat*)ve,xe); vis_TraceGetExit (trace,SYS_ON,&status,&edgenumber, xc,vout,wout,&tout); if(adj[nn][edgenumber-1]) { t = tout; nn = adj[nn][edgenumber-1] - 1; } else { break; } } GLWinXfmPop (glwin); GLWinSwap (glwin); sleep(1); } sleep(5); /* free all objects */ vgl_DrawFunEnd (df); vis_VisContextEnd (vcface); vis_VisContextEnd (vcmark); vis_VisContextEnd (vctrace); vis_ColorMapEnd (cmap); vis_FaceEnd (face); vis_MarkEnd (mark); vis_TraceEnd (trace); GLWinEnd (glwin); return 0; } /*---------------------------------------------------------------------- Utility function to gather element vectors ----------------------------------------------------------------------*/ static void gather(Vfloat x[][3], Vint con[4], Vfloat xe[][3]) { int i, j; for(i = 0; i < 4; i++) { for(j = 0; j < 3; j++) { xe[i][j] = x[con[i]-1][j]; } } }
The stream ribbon consists of a stream line and an adjoining ribbon anchored to the stream line. The twist of the stream ribbon reflects the streamwise curl of the vector field. The initial orientation vector of the stream ribbon is set to (0.,0.,.5). The streamline will propagate in a straight line down the vortex core. The adjoining stream ribbon will twist around the stream line indicating the streamwise vorticity.
#include "base/base.h" #include "vgl/vgl.h" #include "vis/vis.h" #include "glwin.h" static Vfloat xhex[27][3] = { {0.,0.,0.}, {1.,0.,0.}, {2.,0.,0.}, {0.,1.,0.}, {1.,1.,0.}, {2.,1.,0.}, {0.,2.,0.}, {1.,2.,0.}, {2.,2.,0.}, {0.,0.,1.}, {1.,0.,1.}, {2.,0.,1.}, {0.,1.,1.}, {1.,1.,1.}, {2.,1.,1.}, {0.,2.,1.}, {1.,2.,1.}, {2.,2.,1.}, {0.,0.,2.}, {1.,0.,2.}, {2.,0.,2.}, {0.,1.,2.}, {1.,1.,2.}, {2.,1.,2.}, {0.,2.,2.}, {1.,2.,2.}, {2.,2.,2.} }; static Vfloat vhex[27][3] = { {.5,1.,-1.}, {.5,1.,-1.}, {.5,1.,-1.}, {.5,1.,0.}, {.5,1.,0.}, {.5,1.,0.}, {.5,1.,1.}, {.5,1.,1.}, {.5,1.,1.}, {.5,0.,-1.}, {.5,0.,-1.}, {.5,0.,-1.}, {.5,0.,0.}, {.5,0.,0.}, {.5,0.,0.}, {.5,0.,1.}, {.5,0.,1.}, {.5,0.,1.}, {.5,-1.,-1.}, {.5,-1.,-1.}, {.5,-1.,-1.}, {.5,-1.,0.}, {.5,-1.,0.}, {.5,-1.,0.}, {.5,-1.,1.}, {.5,-1.,1.}, {.5,-1.,1.} }; static Vfloat rgb[4][3] = { {.2,.2,.2}, {1.,0.,0.}, {0.,1.,0.}, {0.,0.,1.} }; /*---------------------------------------------------------------------- Generate streamribbon in a 27 node brick element ----------------------------------------------------------------------*/ int main() { vgl_DrawFun *df; vis_VisContext *vc; vis_ColorMap *cmap; vis_Stream *stream; GLWin *glwin; int i; Vfloat x[3], v[3], w[3]; /* create GL device */ glwin = GLWinBegin (); GLWinCreateWindow (glwin,200,200,400,400); GLWinOrtho (glwin,-3.,3.,-3.,3.,-3.,3.); /* create draw function object */ df = vgl_DrawFunBegin(); GLWinDrawFun (glwin,df); /* vis context and set attributes */ vc = vis_VisContextBegin (); vis_VisContextSetStreamType (vc,VIS_STREAMRIBBON); vis_VisContextSetLineWidth (vc,3); vis_VisContextSetSize (vc,.1); vis_VisContextSetColor (vc,1); vis_VisContextSetMinorColor (vc,2); vis_VisContextSetShade (vc,VIS_VERTEXSHADE); /* color map */ cmap = vis_ColorMapBegin (); vis_ColorMapSetType (cmap,COLORMAP_TRUECOLOR); vis_ColorMapSetRGB (cmap,4,0,rgb); /* create stream object and set objects */ stream = vis_StreamBegin (); vis_StreamSetObject (stream,VGL_DRAWFUN,df); vis_StreamSetObject (stream,VIS_VISCONTEXT,vc); vis_StreamSetObject (stream,VIS_COLORMAP,cmap); /* draw stream */ vis_StreamSetTopology (stream,VIS_SHAPEHEX,3,3,3); /* set initial position */ x[0] = 0.; x[1] = 1.; x[2] = 1.; /* set initial orientation vector */ v[0] = 0.; v[1] = 0.; v[2] = .5; w[0] = 0.; w[1] = -.5; w[2] = 0.; for(i = 0; i < 30; i++) { GLWinClear (glwin); GLWinXfmPush (glwin); GLWinRotate (glwin,i*12.,'y'); vis_StreamSetEnter (stream,SYS_ON,x,v,w,0.); vis_StreamCurv (stream,VIS_VECTOR,(Vfloat*)vhex,xhex); GLWinXfmPop (glwin); GLWinSwap (glwin); sleep(1); } sleep(5); /* free all objects */ vgl_DrawFunEnd (df); vis_VisContextEnd (vc); vis_ColorMapEnd (cmap); vis_StreamEnd (stream); GLWinEnd (glwin); return 0; }
#include "base/base.h" #include "vgl/vgl.h" #include "vis/vis.h" #include "glwin.h" static Vfloat rgb[7][3] = { {.2,.2,.2}, {1.,0.,0.}, {0.,1.,0.}, {0.,0.,1.}, {0.,1.,1.}, {1.,0.,1.}, {1.,1.,0.} }; /*---------------------------------------------------------------------- Generate stroked fonts ----------------------------------------------------------------------*/ int main() { vgl_DrawFun *df; vis_VisContext *vc; vis_ColorMap *cmap; vis_Font *font; GLWin *glwin; int i; Vfloat x[3]; /* create GL device */ glwin = GLWinBegin (); GLWinCreateWindow (glwin,100,100,800,400); GLWinOrtho (glwin,-2.,6.,-2.,2.,-2.,2.); /* create drawing function object for GL */ df = vgl_DrawFunBegin (); GLWinDrawFun (glwin,df); /* vis context and set attributes */ vc = vis_VisContextBegin (); vis_VisContextSetColor (vc,4); vis_VisContextSetSize (vc,.1); /* color map */ cmap = vis_ColorMapBegin (); vis_ColorMapSetType (cmap,COLORMAP_TRUECOLOR); vis_ColorMapSetRGB (cmap,7,0,rgb); /* create font object and set objects */ font = vis_FontBegin (); vis_FontSetObject (font,VGL_DRAWFUN,df); vis_FontSetObject (font,VIS_VISCONTEXT,vc); vis_FontSetObject (font,VIS_COLORMAP,cmap); /* draw standard font */ GLWinClear (glwin); x[0] = x[1] = x[2] = 0.; vis_FontSetParami (font,FONT_DIRECTION,VIS_RIGHT); vis_FontText (font,x,"Hello World"); vis_FontSetParami (font,FONT_DIRECTION,VIS_BOTTOM); vis_FontText (font,x,"Hello World"); vis_FontSetParami (font,FONT_DIRECTION,VIS_RIGHT); x[1] = .5; vis_FontText (font,x,"Hello World"); vis_FontSetParamf (font,FONT_ANGLE,30.); vis_FontText (font,x,"Hello World"); vis_FontSetParamf (font,FONT_ANGLE,60.); vis_FontText (font,x,"Hello World"); vis_FontSetParamf (font,FONT_ANGLE,90.); vis_FontText (font,x,"Hello World"); vis_FontSetParamf (font,FONT_ANGLE,0.); GLWinSwap (glwin); sleep(5); /* illustrate expansion, spacing, etc. */ vis_VisContextSetSize (vc,.1); for(i = 0; i < 30; i++) { GLWinClear (glwin); GLWinXfmPush (glwin); GLWinRotate (glwin,i*12.,'x'); x[0] = -1.8; x[1] = 1.5; vis_FontText (font,x,"1234 ABCD abcd !@#$%^&*()_+"); x[0] = -1.8; x[1] = 1.0; vis_FontSetParamf (font,FONT_EXPANSION,.5); vis_FontText (font,x,"1234 ABCD abcd !@#$%^&*()_+"); vis_FontSetParamf (font,FONT_EXPANSION,1.); x[0] = -1.8; x[1] = .5; vis_FontSetParamf (font,FONT_SLANT,.2); vis_FontText (font,x,"1234 ABCD abcd !@#$%^&*()_+"); vis_FontSetParamf (font,FONT_SLANT,0.); x[0] = -1.8; x[1] = 0.; vis_FontSetParamf (font,FONT_SPACING,.2); vis_FontText (font,x,"1234 ABCD abcd !@#$%^&*()_+"); vis_FontSetParamf (font,FONT_SPACING,0.); x[0] = -1.8; x[1] = -.5; vis_FontSetParamf (font,FONT_EXTRUSION,.02); vis_FontText (font,x,"1234 ABCD abcd !@#$%^&*()_+"); x[0] = -1.8; x[1] = -1.; vis_FontSetParamf (font,FONT_EXTRUSION,.05); vis_VisContextSetSize (vc,.2); vis_FontSetParamf (font,FONT_EXPANSION,.5); vis_FontText (font,x,"1234 ABCD abcd !@#$%^&*()_+"); vis_FontSetParamf (font,FONT_EXTRUSION,0.); vis_VisContextSetSize (vc,.1); vis_FontSetParamf (font,FONT_EXPANSION,1.); GLWinXfmPop (glwin); GLWinSwap (glwin); sleep(1); } sleep(5); /* illustrate available fonts */ GLWinClear (glwin); vis_VisContextSetSize (vc,.15); x[0] = -1.8; x[1] = 1.8; vis_FontLoad (font,FONT_GREEK); vis_FontText (font,x,"1234 ABCD abcd !@#$ GREEK"); x[0] = -1.8; x[1] = 1.4; vis_FontLoad (font,FONT_ITALICS); vis_FontText (font,x,"1234 ABCD abcd !@#$ ITALICS"); x[0] = -1.8; x[1] = 1.0; vis_FontLoad (font,FONT_ROMAN1); vis_FontText (font,x,"1234 ABCD abcd !@#$ ROMAN1"); x[0] = -1.8; x[1] = .6; vis_FontLoad (font,FONT_ROMAN2); vis_FontText (font,x,"1234 ABCD abcd !@#$ ROMAN2"); x[0] = -1.8; x[1] = .2; vis_FontLoad (font,FONT_BOLDSCRIPT); vis_FontText (font,x,"1234 ABCD abcd !@#$ BOLDSCRIPT"); /* x[0] = -1.8; x[1] = -.2; vis_FontLoad (font,FONT_FILLROMAN1); vis_FontText (font,x,"1234 ABCD abcd !@#$ FILLROMAN1"); x[0] = -1.8; x[1] = -.6; vis_FontLoad (font,FONT_FILLROMAN2); vis_FontText (font,x,"1234 ABCD abcd !@#$ FILLROMAN2"); x[0] = -1.8; x[1] = -1.0; vis_FontLoad (font,FONT_GOTHIC); vis_FontText (font,x,"1234 ABCD abcd !@#$ GOTHIC"); */ x[0] = -1.8; x[1] = -1.4; vis_FontLoad (font,FONT_SCRIPT); vis_FontText (font,x,"1234 ABCD abcd !@#$ SCRIPT"); x[0] = -1.8; x[1] = -1.8; vis_FontLoad (font,FONT_UNCIAL); vis_FontText (font,x,"1234 ABCD abcd !@#$ UNCIAL"); GLWinSwap (glwin); sleep(5); /* free all objects */ vgl_DrawFunEnd (df); vis_VisContextEnd (vc); vis_ColorMapEnd (cmap); vis_FontEnd (font); GLWinEnd (glwin); return 0; }
#include "base/base.h" #include "vgl/vgl.h" #include "vis/vis.h" #include "glwin.h" static Vfloat rgb[7][3] = { {.2,.2,.2}, {1.,0.,0.}, {0.,1.,0.}, {0.,0.,1.}, {0.,1.,1.}, {1.,0.,1.}, {1.,1.,0.} }; /*---------------------------------------------------------------------- Generate periodic table of glyphs ----------------------------------------------------------------------*/ int main() { vgl_DrawFun *df; vis_VisContext *vc; vis_ColorMap *cmap; vis_Glyph *glyph; GLWin *glwin; int i; Vfloat x[3]; /* create GL device */ glwin = GLWinBegin (); GLWinCreateWindow (glwin,200,200,400,400); GLWinOrtho (glwin,-2.,2.,-2.,2.,-2.,2.); /* create drawing function object for GL */ df = vgl_DrawFunBegin (); GLWinDrawFun (glwin,df); /* vis context and set attributes */ vc = vis_VisContextBegin (); vis_VisContextSetColor (vc,4); vis_VisContextSetRefinement (vc,0); vis_VisContextSetShade (vc,VIS_VERTEXSHADE); /* color map */ cmap = vis_ColorMapBegin (); vis_ColorMapSetType (cmap,COLORMAP_TRUECOLOR); vis_ColorMapSetRGB (cmap,7,0,rgb); /* create glyph object and set objects */ glyph = vis_GlyphBegin (); vis_GlyphSetObject (glyph,VGL_DRAWFUN,df); vis_GlyphSetObject (glyph,VIS_VISCONTEXT,vc); vis_GlyphSetObject (glyph,VIS_COLORMAP,cmap); /* illustrate glyphs */ for(i = 0; i < 30; i++) { GLWinClear (glwin); GLWinXfmPush (glwin); GLWinRotate (glwin,i*12.,'x'); vis_VisContextSetColor (vc,4); x[0] = -1.5; x[1] = 1.5; x[2] = 0.; vis_GlyphArrow2D (glyph,x,.4,.1,.1,0.,1,VIS_ON,VIS_ON,1,1); x[0] = -1.0; x[1] = 1.5; vis_GlyphArrow3D (glyph,x,.4,.1,.1,0.,1,VIS_ON,1,0,1); x[0] = -.5; x[1] = 1.5; vis_GlyphBox (glyph,x,.2,.3,.4,VIS_ON); x[0] = .0; x[1] = 1.5; vis_GlyphCircle (glyph,x,.1,0.,VIS_OFF); x[0] = .5; x[1] = 1.5; vis_GlyphCylinder (glyph,x,.1,.4,0.,1); x[0] = 1.0; x[1] = 1.5; vis_GlyphEllipsoid (glyph,x,.2,.4,.6); x[0] = 1.5; x[1] = 1.5; vis_GlyphRectangle (glyph,x,.2,.4,0.,VIS_OFF); vis_VisContextSetColor (vc,5); x[0] = -1.5; x[1] = 0.5; vis_GlyphSphere (glyph,x,.2,1); x[0] = -1.0; x[1] = 0.5; vis_GlyphCone (glyph,x,.2,.4,0.,1); x[0] = -.5; x[1] = 0.5; vis_GlyphTetrahedron (glyph,x,.2,1); x[0] = .0; x[1] = 0.5; vis_GlyphPyramid (glyph,x,.2,.4,.6); x[0] = .5; x[1] = 0.5; vis_GlyphOctahedron (glyph,x,.2,.4,.6,1); x[0] = 1.0; x[1] = 0.5; vis_GlyphTriaxis (glyph,x,.2,.4,.6,0.); x[0] = 1.5; x[1] = 0.5; vis_GlyphTriangle (glyph,x,.2,1); vis_VisContextSetColor (vc,6); x[0] = -1.5; x[1] = -.5; vis_GlyphDiamond (glyph,x,.2,.15,0); x[0] = -1.0; x[1] = -.5; vis_GlyphHourglass (glyph,x,.2); x[0] = -.5; x[1] = -.5; vis_GlyphGround (glyph,x,.2,0.,0.); x[0] = 0.; x[1] = -.5; vis_GlyphLine (glyph,x,.4,0.); vis_VisContextSetColor (vc,1); vis_VisContextSetRefinement (vc,1); x[0] = -1.5; x[1] = -1.5; vis_GlyphConicalFrustum (glyph,x,.1,.2,.4,0.,1); x[0] = 0.; x[1] = -1.5; vis_GlyphArrow2D3D (glyph,x,1.,.15,.3,0.,1,VIS_ON,1,0,1); x[0] = .5; x[1] = -1.5; vis_GlyphArrow2D3D (glyph,x,1.,.1,.3,0.,2,VIS_ON,1,1,1); vis_VisContextSetColor (vc,4); x[0] = 1.0; x[1] = -1.5; x[2] = 0.; vis_GlyphCircleN (glyph,x,3); x[0] = 1.2; x[1] = -1.5; x[2] = 0.; vis_GlyphCircleN (glyph,x,5); x[0] = 1.4; x[1] = -1.5; x[2] = 0.; vis_GlyphCircleN (glyph,x,7); x[0] = 1.6; x[1] = -1.5; x[2] = 0.; vis_GlyphCircleN (glyph,x,9); GLWinXfmPop (glwin); GLWinSwap (glwin); sleep(1); } sleep(5); /* free all objects */ vgl_DrawFunEnd (df); vis_VisContextEnd (vc); vis_ColorMapEnd (cmap); vis_GlyphEnd (glyph); GLWinEnd (glwin); return 0; }
It is assumed that the length of the restraint arrow is 1.5. This length must, in general, be determined from examining the characteristic length scale of the model with which it is being drawn. The example suggests ratios of the length to be applied to sizes assigned to the arrow head, etc. The arrow tip is located at the point of restraint and the direction is in the direction of restraint. For translational restraints a single headed arrow is used. Two different styles of arrows and hatch mark are used. The first is a planar arrow with a single hatch mark. The second is mixed arrow using a 3D head and a line tail with hatch marks in the x' and y' directions. For rotational restraints a double headed arrow is used. A full 3D arrow representation is used with a thin 3D disk used as a hatch mark.
#include "base/base.h" #include "vgl/vgl.h" #include "vis/vis.h" #include "glwin.h" /*---------------------------------------------------------------------- Draw Displacement Restraints Using Glyph ----------------------------------------------------------------------*/ int main() { vgl_DrawFun *df; vis_VisContext *vc; vis_Glyph *glyph; GLWin *glwin; int i; Vfloat c[3], x[3], v[3]; Vfloat l, r, h, off, hatchoff, hatchh; Vint head; Vfloat xstg[3] = {-1.5,1.5,0.}; /* create GL device */ glwin = GLWinBegin (); GLWinCreateWindow (glwin,200,200,400,400); GLWinOrtho (glwin,-2.,2.,-2.,2.,-2.,2.); /* create drawing function object for GL */ df = vgl_DrawFunBegin (); GLWinDrawFun (glwin,df); /* vis context and set attributes */ vc = vis_VisContextBegin (); vis_VisContextSetRefinement (vc,0); vis_VisContextSetShade (vc,VIS_VERTEXSHADE); /* create glyph object and set objects */ glyph = vis_GlyphBegin (); vis_GlyphSetObject (glyph,VGL_DRAWFUN,df); vis_GlyphSetObject (glyph,VIS_VISCONTEXT,vc); /* draw in light blue */ c[0] = 0.6; c[1] = 0.6; c[2] = 1.0; vgl_DrawFunColor (df,c); /* orient z' direction of arrow along x axis */ v[0] = 1.; v[1] = 0.; v[2] = 0.; vis_GlyphSetOrientZ (glyph,v); /* arrow tip at 0.,0.,0. */ x[0] = 0.; x[1] = 0.; x[2] = 0.; /* length of restraint arrow */ l = 1.5; /* make radius of arrow head .125 of length */ r = .125*l; /* make height of arrow head equal to twice the radius */ h = 2.*r; /* do not offset arrow head from tip */ off = 0.; /* use 1 headed arrow for displacment restraint */ head = 1; /* set hatch mark offset .75 of arrow length back from tip */ hatchoff = -.75*l; /* translational restraint using planar (x',z') arrow */ for(i = 0; i < 19; i++) { GLWinClear (glwin); vgl_DrawFunText (df,xstg,"Planar head, wireframe tail"); GLWinXfmPush (glwin); GLWinRotate (glwin,-i*10.,'y'); /* draw 2D arrow with tail, filled, normal style, capped */ vis_GlyphArrow2D (glyph,x,l,r,h,off,head,VIS_ON,VIS_ON,VIS_OFF,VIS_ON); /* add hatch mark in x' direction only */ vis_GlyphTriaxis (glyph,x,h,0.,0.,hatchoff); GLWinXfmPop (glwin); GLWinSwap (glwin); sleep(1); } /* translational restraint using mixed arrow */ for(i = 0; i < 19; i++) { GLWinClear (glwin); vgl_DrawFunText (df,xstg,"Tetrahedral head, wireframe tail"); GLWinXfmPush (glwin); GLWinRotate (glwin,-i*10.,'y'); /* draw mixed 2D,3D arrow */ vis_GlyphArrow2D3D (glyph,x,l,r,h,off,head,VIS_ON,VIS_ON,VIS_OFF,VIS_ON); /* add hatch mark in x' and y' directions */ vis_GlyphTriaxis (glyph,x,h,h,0.,hatchoff); GLWinXfmPop (glwin); GLWinSwap (glwin); sleep(1); } /* use 2 headed arrow for rotation restraint */ head = 2; /* thin hatch mark disk */ hatchh = .025*l; /* use higher refinement with circular glyphs */ vis_VisContextSetRefinement (vc,2); /* illustrate rotational restraint using 3D arrow */ for(i = 0; i < 19; i++) { GLWinClear (glwin); vgl_DrawFunText (df,xstg,"Conical head, cylindrical tail"); GLWinXfmPush (glwin); GLWinRotate (glwin,-i*10.,'y'); /* draw 3D arrow with tail, filled, normal style, capped */ vis_GlyphArrow3D (glyph,x,l,r,h,off,head,VIS_ON,VIS_ON,VIS_OFF,VIS_ON); /* add hatch mark as thin disk */ vis_GlyphDisk (glyph,x,r,hatchh,hatchoff,VIS_ON); GLWinXfmPop (glwin); GLWinSwap (glwin); sleep(1); } sleep(2); /* free all objects */ vgl_DrawFunEnd (df); vis_VisContextEnd (vc); vis_GlyphEnd (glyph); GLWinEnd (glwin); return 0; }
#include "base/base.h" #include "vgl/vgl.h" #include "vis/vis.h" #include "glwin.h" static Vfloat rgb[7][3] = { {.8,.8,.8}, {1.,0.,0.}, {0.,1.,0.}, {0.,0.,1.}, {0.,1.,1.}, {1.,0.,1.}, {1.,1.,0.} }; /*---------------------------------------------------------------------- Draw Axes ----------------------------------------------------------------------*/ int main() { vgl_DrawFun *df; vis_VisContext *vc; vis_Levels *levels; vis_ColorMap *cmap; vis_Axis *axis; GLWin *glwin; int i; Vfloat x[3], path[3], plane[3]; /* create GL device */ glwin = GLWinBegin (); GLWinCreateWindow (glwin,200,200,400,400); GLWinOrtho (glwin,-2.,2.,-2.,2.,-2.,2.); /* create drawing function object for GL */ df = vgl_DrawFunBegin (); GLWinDrawFun (glwin,df); /* vis context and set attributes */ vc = vis_VisContextBegin (); vis_VisContextSetColor (vc,4); vis_VisContextSetSize (vc,.025); vis_VisContextSetLineStyle (vc,VIS_CYLINDER); vis_VisContextSetXYZColor (vc,0,0,0); vis_VisContextSetFill (vc,VIS_OFF); vis_VisContextSetMinorColor (vc,6); vis_VisContextSetMinorSize (vc,.08); vis_VisContextSetFormat (vc,VIS_FFORMAT); /* Axis levels */ levels = vis_LevelsBegin (); /* color map */ cmap = vis_ColorMapBegin (); vis_ColorMapSetType (cmap,COLORMAP_TRUECOLOR); vis_ColorMapSetRGB (cmap,7,0,rgb); /* create axis object and set objects */ axis = vis_AxisBegin (); vis_AxisSetObject (axis,VGL_DRAWFUN,df); vis_AxisSetObject (axis,VIS_VISCONTEXT,vc); vis_AxisSetObject (axis,VIS_COLORMAP,cmap); vis_AxisSetObject (axis,VIS_LEVELS,levels); /* illustrate axes */ for(i = 0; i < 30; i++) { GLWinClear (glwin); GLWinXfmPush (glwin); GLWinRotate (glwin,i*1.,'X'); GLWinRotate (glwin,-i*1.,'Y'); /* draw x axis */ x[0] = -1.2; x[1] = -1.2; x[2] = 0.; vis_LevelsDef (levels,LEVELS_LINEAR,6); vis_LevelsSetMinMax (levels,0.,100.); vis_LevelsGenerate (levels,LEVELS_PADNONE); path[0] = 1.; path[1] = 0.; path[2] = 0.; plane[0] = 0.; plane[1] = 1.; plane[2] = 0.; vis_AxisSetPlane (axis,path,plane); vis_AxisSetParami (axis,AXIS_SENSE,VIS_OFF); vis_AxisPath (axis,x,3.,"X axis","World Coordinate"); vis_AxisPlane (axis,x,3.,2.,"",""); vis_AxisProjection (axis,x,3.,2.,"",""); /* draw y axis */ vis_LevelsDef (levels,LEVELS_LINEAR,4); vis_LevelsSetMinMax (levels,0.,60.); vis_LevelsGenerate (levels,LEVELS_PADNONE); path[0] = 0.; path[1] = 1.; path[2] = 0.; plane[0] = 1.; plane[1] = 0.; plane[2] = 0.; vis_AxisSetPlane (axis,path,plane); vis_AxisSetParami (axis,AXIS_SENSE,VIS_ON); /* rotate labels by -90. degrees */ vis_AxisSetParami (axis,AXIS_ROTATELABEL,AXIS_ROTATELABEL_PLUS90); vis_AxisPath (axis,x,2.,"Y axis",""); vis_AxisSetParami (axis,AXIS_ROTATELABEL,VIS_OFF); /* draw z axis */ vis_LevelsDef (levels,LEVELS_LINEAR,3); vis_LevelsSetMinMax (levels,0.,1000.); vis_LevelsGenerate (levels,LEVELS_PADNONE); path[0] = 0.; path[1] = 0.; path[2] = 1.; plane[0] = 0.; plane[1] = 1.; plane[2] = 0.; vis_AxisSetPlane (axis,path,plane); vis_AxisSetParami (axis,AXIS_SENSE,VIS_OFF); vis_AxisPath (axis,x,2.,"Z axis",""); GLWinXfmPop (glwin); GLWinSwap (glwin); sleep(1); } sleep(5); /* free all objects */ vgl_DrawFunEnd (df); vis_VisContextEnd (vc); vis_ColorMapEnd (cmap); vis_LevelsEnd (levels); vis_AxisEnd (axis); GLWinEnd (glwin); return 0; }
The outside loop changes the clipping mode. The first time through the loop, the mode ISOCLIP_ANY will clip away a face, edge or node if it is clipped by any isosurface, the second time through the loop, the mode ISOCLIP_ALL will clip away a face, edge or node only if it is clipped by all isosurfaces. The next loop alters the isosurface values so that they appear to slowly propagate, clipping away successively greater amounts of the faces. The isosurfaces are actually propagated twice. The first time the isosurfaces are defined using scalar data fields to represent the functions of the coordinates. The second time the isosurfaces are defined explicitly using coordinate clipping.
The IsoClip module contains a definition of the active clipping isosurfaces. In the first case, Note that the IsoClip object is given a pointer to a one dimensional array for each clipping isosurface using vis_IsoClipSetDataPtr. Each of these arrays is to contain the current values of the scalar field corresponding to each isosurface for the face to be drawn with each call to vis_FaceCurv and the nodes to be drawn with each call to vis_MarkPnt. In the second case the first isosurface in the x coordinate is defined directly as the global x coordinate of each node, while the second isosurface can be defined as the radial coordinate of each node expressed in a cylindrical coordinate system positioned at the origin. This coordinate system is defined using a CoordSys object. The CoordSys object is set into the IsoClip for index = 1 using vis_IsoClipSetCoordSys.
#include "base/base.h" #include "vgl/vgl.h" #include "vis/vis.h" #include "glwin.h" #define MAG(x) sqrt( ((x)[0]*(x)[0] + (x)[1]*(x)[1] + (x)[2]*(x)[2]) ) /* anchor location of text string */ static Vfloat xtxt[3] = { -11., 11., 0. }; static Vfloat ctxt[3] = { 1., 1., 1. }; /*---------------------------------------------------------------------- Clip Finite Element Faces to Isosurfaces ----------------------------------------------------------------------*/ int main() { vgl_DrawFun *df; vis_VisContext *vc; vis_ColorMap *cmap; vis_Face *face; vis_Mark *mark; vis_IsoClip *isoclip; vis_CoordSys *coordsys; GLWin *glwin; int i, j, k, n; Vfloat c[3]; Vfloat xf[4][3]; Vfloat val0, sf0[4], val1, sf1[4]; Vint mode; /* create GL device */ glwin = GLWinBegin (); GLWinCreateWindow (glwin,200,200,400,400); GLWinOrtho (glwin,-12.,12.,-12.,12.,-12.,12.); /* create drawing function object for GL */ df = vgl_DrawFunBegin (); GLWinDrawFun (glwin,df); /* vis context and set attributes */ vc = vis_VisContextBegin (); vis_VisContextSetColor (vc,1); vis_VisContextSetMinorColor (vc,2); vis_VisContextSetEdge (vc,VIS_ON); vis_VisContextSetFill (vc,VIS_ON); vis_VisContextSetMarkerType (vc,VIS_POINT4); vis_VisContextSetMapColor (vc,VIS_MAPCOLOR_NONE); /* color map */ cmap = vis_ColorMapBegin (); vis_ColorMapSetType (cmap,COLORMAP_TRUECOLOR); /* gray */ c[0] = .5; c[1] = .5; c[2] = .5; vis_ColorMapSetRGB (cmap,1,1,(Vfloat(*)[3])c); /* white */ c[0] = 1.0; c[1] = 1.0; c[2] = 1.0; vis_ColorMapSetRGB (cmap,1,2,(Vfloat(*)[3])c); /* red */ c[0] = 1.0; c[1] = .0; c[2] = .0; vis_ColorMapSetRGB (cmap,1,3,(Vfloat(*)[3])c); /* isosurface clipping object */ isoclip = vis_IsoClipBegin (); /* create face object and set objects */ face = vis_FaceBegin (); vis_FaceSetObject (face,VGL_DRAWFUN,df); vis_FaceSetObject (face,VIS_VISCONTEXT,vc); vis_FaceSetObject (face,VIS_COLORMAP,cmap); vis_FaceSetObject (face,VIS_ISOCLIP,isoclip); /* create mark object and set objects */ mark = vis_MarkBegin (); vis_MarkSetObject (mark,VGL_DRAWFUN,df); vis_MarkSetObject (mark,VIS_VISCONTEXT,vc); vis_MarkSetObject (mark,VIS_COLORMAP,cmap); vis_MarkSetObject (mark,VIS_ISOCLIP,isoclip); /* data based clipping */ vis_IsoClipSetDataPtr (isoclip,0,sf0); vis_IsoClipSetDataPtr (isoclip,1,sf1); /* first ANY mode and then ALL mode */ for(n = 0; n < 2; n++) { if(n == 0) { mode = ISOCLIP_ANY; } else { mode = ISOCLIP_ALL; } vis_IsoClipSetMode (isoclip,mode); /* alter isosurface clipping values 20 times */ for(i = 0; i < 20; i++) { GLWinClear (glwin); val0 = 10. - .3333 * i; vis_IsoClipSetType (isoclip,0,ISOCLIP_DATA,ISOCLIP_HITHER,val0); val1 = 12. - .3333 * i; vis_IsoClipSetType (isoclip,1,ISOCLIP_DATA,ISOCLIP_HITHER,val1); /* draw 10 by 10 grid of faces */ for(j = 0; j < 10; j++) { for(k = 0; k < 10; k++) { xf[0][0] = j; xf[0][1] = k; xf[0][2] = 0; xf[1][0] = j+1; xf[1][1] = k; xf[1][2] = 0; xf[2][0] = j+1; xf[2][1] = k+1; xf[2][2] = 0; xf[3][0] = j; xf[3][1] = k+1; xf[3][2] = 0; sf0[0] = xf[0][0]; sf0[1] = xf[1][0]; sf0[2] = xf[2][0]; sf0[3] = xf[3][0]; sf1[0] = MAG(xf[0]); sf1[1] = MAG(xf[1]); sf1[2] = MAG(xf[2]); sf1[3] = MAG(xf[3]); vis_VisContextSetColor (vc,1); vis_FaceCurv (face,xf,VIS_NODATA,NULL); vis_VisContextSetColor (vc,3); vis_MarkPnt (mark,4,xf); } } GLWinColor (glwin,ctxt); if(mode == ISOCLIP_ANY) { GLWinText (glwin,xtxt,"Data Clipping, ANY mode"); } else { GLWinText (glwin,xtxt,"Data Clipping, ALL mode"); } GLWinSwap (glwin); sleep(1); } } /* do the same thing with coordinate based clipping */ /* create cylindrical system for radial clipping */ /* default system at origin and aligned to global */ coordsys = vis_CoordSysBegin (); vis_CoordSysDef (coordsys,SYS_CYLINDRICAL); vis_IsoClipSetCoordSys (isoclip,1,coordsys); for(n = 0; n < 2; n++) { if(n == 0) { mode = ISOCLIP_ANY; } else { mode = ISOCLIP_ALL; } vis_IsoClipSetMode (isoclip,mode); /* alter isosurface clipping values 20 times */ for(i = 0; i < 20; i++) { GLWinClear (glwin); val0 = 10. - .3333 * i; vis_IsoClipSetType (isoclip,0,ISOCLIP_X,ISOCLIP_HITHER,val0); val1 = 12. - .3333 * i; /* the radial coordinate is "X" */ vis_IsoClipSetType (isoclip,1,ISOCLIP_X,ISOCLIP_HITHER,val1); /* draw 10 by 10 grid of faces */ for(j = 0; j < 10; j++) { for(k = 0; k < 10; k++) { xf[0][0] = j; xf[0][1] = k; xf[0][2] = 0; xf[1][0] = j+1; xf[1][1] = k; xf[1][2] = 0; xf[2][0] = j+1; xf[2][1] = k+1; xf[2][2] = 0; xf[3][0] = j; xf[3][1] = k+1; xf[3][2] = 0; vis_VisContextSetColor (vc,1); vis_FaceCurv (face,xf,VIS_NODATA,NULL); vis_VisContextSetColor (vc,3); vis_MarkPnt (mark,4,xf); } } GLWinColor (glwin,ctxt); if(mode == ISOCLIP_ANY) { GLWinText (glwin,xtxt,"Coordinate Clipping, ANY mode"); } else { GLWinText (glwin,xtxt,"Coordinate Clipping, ALL mode"); } GLWinSwap (glwin); sleep(1); } } sleep(5); /* free all objects */ vgl_DrawFunEnd (df); vis_VisContextEnd (vc); vis_ColorMapEnd (cmap); vis_FaceEnd (face); vis_MarkEnd (mark); vis_IsoClipEnd (isoclip); vis_CoordSysEnd (coordsys); GLWinEnd (glwin); return 0; }
A 10 by 10 by 10 grid of hexahedral elements to be clipped is generated. The cylindrical volume is specified by three coordinate surfaces defined in a cylindrical coordinate system represented by a single CoordSys object. The three coordinate surfaces are a radial surface at a radius of 3.5 and two axial surfaces at 2.2 and 7.8. These three surface completely enclose a cylindrical volume and are entered into a IsoClip object.
After all the hexahedral cells are traversed, the Connect object in the user defined object, tobj, will contain all generated polyhedra. The HashTable and Concat objects will contain all the scalar field data interpolated to the nodes of the polyhedra. The function print_info traverses all the polyhedra, computing the volume with the ElemChk module. Finally, an example of printing the nodal coordinates and interpolated data for the first polyhedron is shown.
#include "base/base.h" #include "vgl/vgl.h" #include "vis/vis.h" static void print_info(vis_Connect *connect, vsy_HashTable *ht, vsy_Concat *cc); typedef struct Tobj { vis_Connect *connect; Vint numnp; Vint numel; vsy_HashTable *hashtable; vsy_Concat *concat; } Tobj; static void TPolygonData(Tobj *t, Vint type, Vint npts, Vfloat x[][3], Vint nrws, Vfloat d[], Vint vflag, Vfloat v[]) { Vint i; Vint ix[8]; void *pntr; /* set element topology */ t->numel += 1; if(npts == 4) { vis_ConnectSetTopology (t->connect,t->numel,VIS_SHAPETET,0,0,0); } else if(npts == 5) { vis_ConnectSetTopology (t->connect,t->numel,VIS_SHAPEPYR,0,0,0); } else if(npts == 6) { vis_ConnectSetTopology (t->connect,t->numel,VIS_SHAPEWED,0,0,0); } else if(npts == 8) { vis_ConnectSetTopology (t->connect,t->numel,VIS_SHAPEHEX,0,0,0); } /* set node coordinates */ for(i = 0; i < npts; i++) { t->numnp += 1; ix[i] = t->numnp; vis_ConnectSetCoords (t->connect,t->numnp,x[i]); } /* set element node connectivity */ vis_ConnectSetElemNode (t->connect,t->numel,ix); /* store data */ vsy_ConcatAdd (t->concat,nrws*npts*sizeof(Vfloat),d); vsy_ConcatRef (t->concat,&pntr); vsy_HashTableInsert (t->hashtable,t->numel,pntr); } /*---------------------------------------------------------------------- Clip Finite Elements to a Volume ----------------------------------------------------------------------*/ int main() { vgl_DrawFun *df; vis_VisContext *vc; vis_Cell *cell; vis_IsoClip *isoclip; vis_DataInt *dataint; vis_CoordSys *coordsys; Vfloat xc[8][3], d[8]; Vfloat xo[3], tm[3][3]; int i, j, k, n; Tobj tobj; /* create draw function, with user object tobj */ df = vgl_DrawFunBegin (); vgl_DrawFunSetObj (df,(Vobject*)&tobj); vgl_DrawFunAPI (df,DRAWFUN_APIRETURN); vgl_DrawFunSet (df,DRAWFUN_POLYGONDATA,(Vfunc*)TPolygonData); tobj.connect = vis_ConnectBegin (); tobj.numel = 0; tobj.numnp = 0; tobj.hashtable = vsy_HashTableBegin (); tobj.concat = vsy_ConcatBegin (); /* vis context and set attributes */ vc = vis_VisContextBegin (); vis_VisContextSetDraw (vc,VIS_OFF); vis_VisContextSetFlags (vc,VIS_CREATEPOLYHEDRON); /* define a cylindrical coordinate system */ coordsys = vis_CoordSysBegin (); vis_CoordSysDef (coordsys,SYS_CYLINDRICAL); xo[0] = 4.; xo[1] = 4.; xo[2] = 0.; tm[0][0] = 1.; tm[1][0] = 0.; tm[2][0] = 0.; tm[0][1] = 0.; tm[1][1] = 1.; tm[2][1] = 0.; tm[0][2] = 0.; tm[1][2] = 0.; tm[2][2] = 1.; vis_CoordSysSetOriginTriad (coordsys,xo,tm); /* isosurface clipping object */ isoclip = vis_IsoClipBegin (); vis_IsoClipSetCoordSys (isoclip,0,coordsys); vis_IsoClipSetCoordSys (isoclip,1,coordsys); vis_IsoClipSetCoordSys (isoclip,2,coordsys); /* clip to a cylinder, radius=3.5, bottom=2.2, top=7.8 */ vis_IsoClipSetType (isoclip,0,ISOCLIP_X,ISOCLIP_HITHER,3.5); vis_IsoClipSetType (isoclip,1,ISOCLIP_Z,ISOCLIP_YON,2.2); vis_IsoClipSetType (isoclip,2,ISOCLIP_Z,ISOCLIP_HITHER,7.8); /* data interpolation object for scalar field */ dataint = vis_DataIntBegin (); vis_DataIntSetDataPtr (dataint,0,1,d); /* create cell object and set objects */ cell = vis_CellBegin (); vis_CellSetObject (cell,VGL_DRAWFUN,df); vis_CellSetObject (cell,VIS_VISCONTEXT,vc); vis_CellSetObject (cell,VIS_ISOCLIP,isoclip); vis_CellSetObject (cell,VIS_DATAINT,dataint); vis_CellSetTopology (cell,VIS_SHAPEHEX,2,0,0); /* process cell volumes, 1000 unit cubes */ for(k = 0; k < 10; k++) { for(j = 0; j < 10; j++) { for(i = 0; i < 10; i++) { xc[0][0] = i; xc[0][1] = j; xc[0][2] = k; xc[1][0] = i+1; xc[1][1] = j; xc[1][2] = k; xc[2][0] = i+1; xc[2][1] = j+1; xc[2][2] = k; xc[3][0] = i; xc[3][1] = j+1; xc[3][2] = k; xc[4][0] = i; xc[4][1] = j; xc[4][2] = k+1; xc[5][0] = i+1; xc[5][1] = j; xc[5][2] = k+1; xc[6][0] = i+1; xc[6][1] = j+1; xc[6][2] = k+1; xc[7][0] = i; xc[7][1] = j+1; xc[7][2] = k+1; /* generate a scalar data field, x + y**2 */ for(n = 0; n < 8; n++) { d[n] = xc[n][0] + xc[n][1]*xc[n][1]; } vis_CellCurv (cell,xc); } } } /* print some information about the resulting polyhedra */ print_info (tobj.connect, tobj.hashtable, tobj.concat); /* clean up tobj */ vis_ConnectEnd (tobj.connect); vsy_HashTableEnd (tobj.hashtable); vsy_ConcatEnd (tobj.concat); /* free all objects */ vgl_DrawFunEnd (df); vis_VisContextEnd (vc); vis_CellEnd (cell); vis_IsoClipEnd (isoclip); vis_DataIntEnd (dataint); vis_CoordSysEnd (coordsys); return 0; } /*---------------------------------------------------------------------- print volume information ----------------------------------------------------------------------*/ static void print_info(vis_Connect *connect, vsy_HashTable *ht, vsy_Concat *cc) { Vint i; Vint index; Vint numnp, numel; vis_ElemChk *elemchk; vis_GridFun *gf; Vfloat s[ELEMCHK_MAX]; Vfloat volume; Vint nix, ix[8]; Vfloat *d, x[8][3]; /* write NASTRAN bulk data file of polyhedra */ vis_ConnectWrite (connect,SYS_NASTRAN_BULKDATA,"exam9a.bdf"); vis_ConnectNumber (connect,SYS_NODE,&numnp); vis_ConnectNumber (connect,SYS_ELEM,&numel); printf("number of nodes= %d\n",numnp); printf("number of elems= %d\n",numel); /* compute volume */ gf = vis_GridFunBegin (); vis_ConnectGridFun (connect,gf); elemchk = vis_ElemChkBegin (); vis_ElemChkSetObject (elemchk,VIS_GRIDFUN,gf); vis_ElemChkSetType (elemchk,ELEMCHK_JACOBIAN_SUM,SYS_ON); volume = 0.; for(i = 1; i <= numel; i++) { vis_ElemChkData (elemchk,i,s); volume += s[ELEMCHK_JACOBIAN_SUM]; } printf("volume= %f\n",volume); /* delete objects */ vis_GridFunEnd (gf); vis_ElemChkEnd (elemchk); /* print data and coordinates of first polyhedron*/ index = 1; vsy_HashTableLookup (ht,index,(Vobject**)&d); vis_ConnectElemNode (connect,index,&nix,ix); vis_ConnectCoords (connect,nix,ix,x); for(i = 0; i < nix; i++) { printf(" x= %f, y= %f, z= %f, d= %f\n",x[i][0],x[i][1],x[i][2],d[i]); } }
#include "base/base.h" #include "vgl/vgl.h" #include "vis/vis.h" #include "glwin.h" /* useful macro for magnitude of a vector */ #define MAG(x) sqrt( ((x)[0]*(x)[0] + (x)[1]*(x)[1] + (x)[2]*(x)[2]) ) /* anchor location of text string */ static Vfloat xtxt[3] = { -11., 11., 0. }; /* colors for text, polygon, polyline */ static Vfloat ctxt[3] = { 1., 1., 1. }; static Vfloat cpgn[3] = { 1., 0., 1. }; static Vfloat cpln[3] = { 1., 1., 1. }; /*---------------------------------------------------------------------- Clip Graphics Primitives to Isosurfaces Using PrmClp ----------------------------------------------------------------------*/ int main() { vgl_DrawFun *df; vgl_DrawFun *dfpc; vis_IsoClip *isoclip; vis_PrmClp *prmclp; vis_CoordSys *coordsys; GLWin *glwin; int i, j, k; Vfloat xf[4][3]; Vfloat val0, val1; Vfloat sf0[4], sf1[4]; /* create GL device */ glwin = GLWinBegin (); GLWinCreateWindow (glwin,200,200,400,400); GLWinOrtho (glwin,-12.,12.,-12.,12.,-12.,12.); /* create drawing function object for GL */ df = vgl_DrawFunBegin (); GLWinDrawFun (glwin,df); /* create isosurface clipping object */ isoclip = vis_IsoClipBegin (); vis_IsoClipSetMode (isoclip,ISOCLIP_ANY); /* create drawing function object for PrmClp */ dfpc = vgl_DrawFunBegin (); /* create primitive clipping object */ prmclp = vis_PrmClpBegin (); vis_PrmClpDrawFun (prmclp,dfpc); /* set isosurface clipping object */ vis_PrmClpSetObject (prmclp,VIS_ISOCLIP,isoclip); /* set output drawing function to GLWin */ vis_PrmClpSetObject (prmclp,VIS_ISOCLIP,isoclip); vis_PrmClpSetObject (prmclp,VGL_DRAWFUN,df); /* data based clipping */ vis_IsoClipSetDataPtr (isoclip,0,sf0); vis_IsoClipSetDataPtr (isoclip,1,sf1); /* alter isosurface clipping values 20 times */ for(i = 0; i < 20; i++) { GLWinClear (glwin); val0 = 10. - .3333 * i; vis_IsoClipSetType (isoclip,0,ISOCLIP_DATA,ISOCLIP_HITHER,val0); val1 = 12. - .3333 * i; vis_IsoClipSetType (isoclip,1,ISOCLIP_DATA,ISOCLIP_HITHER,val1); /* draw 10 by 10 grid of faces */ for(j = 0; j < 10; j++) { for(k = 0; k < 10; k++) { xf[0][0] = j; xf[0][1] = k; xf[0][2] = 0; xf[1][0] = j+1; xf[1][1] = k; xf[1][2] = 0; xf[2][0] = j+1; xf[2][1] = k+1; xf[2][2] = 0; xf[3][0] = j; xf[3][1] = k+1; xf[3][2] = 0; sf0[0] = xf[0][0]; sf0[1] = xf[1][0]; sf0[2] = xf[2][0]; sf0[3] = xf[3][0]; sf1[0] = MAG(xf[0]); sf1[1] = MAG(xf[1]); sf1[2] = MAG(xf[2]); sf1[3] = MAG(xf[3]); GLWinColor (glwin,cpgn); vgl_DrawFunPolygon (dfpc,VGL_POLYGON,4,xf,VGL_NOSHADE,NULL); GLWinColor (glwin,cpln); vgl_DrawFunPolyLine (dfpc,VGL_LINELOOP,4,xf); } } GLWinColor (glwin,ctxt); GLWinText (glwin,xtxt,"Data Clipping"); GLWinSwap (glwin); sleep(1); } /* coordinate based clipping */ /* create cylindrical system for radial clipping */ /* default system at origin and aligned to global */ coordsys = vis_CoordSysBegin (); vis_CoordSysDef (coordsys,SYS_CYLINDRICAL); vis_IsoClipSetCoordSys (isoclip,1,coordsys); /* alter isosurface clipping values 20 times */ for(i = 0; i < 20; i++) { GLWinClear (glwin); val0 = 10. - .3333 * i; vis_IsoClipSetType (isoclip,0,ISOCLIP_X,ISOCLIP_HITHER,val0); val1 = 12. - .3333 * i; /* the radial coordinate is "X" */ vis_IsoClipSetType (isoclip,1,ISOCLIP_X,ISOCLIP_HITHER,val1); /* draw 10 by 10 grid of faces */ for(j = 0; j < 10; j++) { for(k = 0; k < 10; k++) { xf[0][0] = j; xf[0][1] = k; xf[0][2] = 0; xf[1][0] = j+1; xf[1][1] = k; xf[1][2] = 0; xf[2][0] = j+1; xf[2][1] = k+1; xf[2][2] = 0; xf[3][0] = j; xf[3][1] = k+1; xf[3][2] = 0; GLWinColor (glwin,cpgn); vgl_DrawFunPolygon (dfpc,VGL_POLYGON,4,xf,VGL_NOSHADE,NULL); GLWinColor (glwin,cpln); vgl_DrawFunPolyLine (dfpc,VGL_LINELOOP,4,xf); } } GLWinColor (glwin,ctxt); GLWinText (glwin,xtxt,"Coordinate Clipping"); GLWinSwap (glwin); sleep(1); } sleep(5); /* free all objects */ vgl_DrawFunEnd (df); vgl_DrawFunEnd (dfpc); vis_IsoClipEnd (isoclip); vis_PrmClpEnd (prmclp); vis_CoordSysEnd (coordsys); GLWinEnd (glwin); return 0; }
The isovalue type VIS_ISOVALTEXTURE relies upon texture mapping to be supported in the graphics subsystem. When this isovalue type is used, the polygons sent to the graphics subsystem contain one dimensional texture coordinates which interpolate a one dimensional texture representing the color mapping to scalar field which has been defined by the ColorMap and Levels objects. The function vis_ColorMapLevelsGetColors is designed specifically to generate the proper texture map to be used. In this example a banded texture is generated by calling this function with COLORMAP_FRINGE. A continuous tone texture may be generated by using COLORMAP_TONE. Generally it is good practice to make the texture a length of 256. If the texture is smaller, poor results may occur with large polygons. The isovalue type VIS_ISOVALTEXTURE may not yield results identical to the isovalue type VIS_ISOVALFRINGE for non triangular elements.
This example is implemented using a VglTools interface in file exam10vgl.c.
#include "base/base.h" #include "vgl/vgl.h" #include "vis/vis.h" #include "glwin.h" void gatherx(Vfloat x[][3], Vint npts, Vint con[], Vfloat xe[][3]); void gathers(Vfloat s[], Vint npts, Vint con[], Vfloat se[]); /* Finite Element Model */ #define MAX_ELEM 2 #define MAX_NODE 5 static Vfloat x[MAX_NODE][3] = { {0.,0.,0.}, {1.,0.,0.}, {2.,0.,0.}, {0.,1.,0.}, {1.,1.,0.} }; static Vfloat s[MAX_NODE] = { 1., 2., 3.5, 4., 3. }; static Vint numconn[MAX_ELEM] = { 4, 3 }; static Vint conn[MAX_ELEM][4] = { {1, 2, 5, 4}, {2, 3, 5, 0} }; static Vint shap[MAX_ELEM] = { VIS_SHAPEQUAD, VIS_SHAPETRI }; /* Isovalue Types */ static Vint isovaltype[6] = { VIS_ISOVALPOINT, VIS_ISOVALLINE, VIS_ISOVALFRINGE, VIS_ISOVALTEXTURE, VIS_ISOVALTONE, VIS_ISOVALGOURAUD }; static Vchar *isovalname[6] = { "VIS_ISOVALPOINT", "VIS_ISOVALLINE", "VIS_ISOVALFRINGE", "VIS_ISOVALTEXTURE", "VIS_ISOVALTONE", "VIS_ISOVALGOURAUD" }; static Vfloat xname[3] = { 0., 2., 0. }; static Vfloat cname[3] = { 1., 1., 1. }; static Vfloat xref[3] = { 0., 2.25, 0. }; /*---------------------------------------------------------------------- Draw Contours on Element Faces ----------------------------------------------------------------------*/ int main() { vgl_DrawFun *df; vis_VisContext *vc; vis_Levels *levels; vis_ColorMap *cmap; vis_Contour *contour; GLWin *glwin; int i, j, k; Vint nlevels; Vfloat xe[4][3], se[4]; Vfloat ctexture[256][3]; Vchar text[33]; /* create GL device */ glwin = GLWinBegin (); GLWinCreateWindow (glwin,200,200,400,400); GLWinOrtho (glwin,-1.,3.,-1.,3.,-2.,2.); /* create draw function object for GL */ df = vgl_DrawFunBegin (); GLWinDrawFun (glwin,df); /* vis context and set attributes */ vc = vis_VisContextBegin (); /* levels, set twelve evenly spaced levels */ levels = vis_LevelsBegin (); nlevels = 12; vis_LevelsDef (levels,LEVELS_LINEAR,nlevels); vis_LevelsSetMinMax (levels,1.,4.); vis_LevelsGenerate (levels,LEVELS_PADTOP); /* color map */ cmap = vis_ColorMapBegin (); vis_ColorMapRamp (cmap,nlevels,1,COLORMAP_HUE); vis_ColorMapLevelsGetColors (cmap,levels,COLORMAP_FRINGE,256,ctexture); /* create contour object and set objects */ contour = vis_ContourBegin (); vis_ContourSetObject (contour,VGL_DRAWFUN,df); vis_ContourSetObject (contour,VIS_VISCONTEXT,vc); vis_ContourSetObject (contour,VIS_LEVELS,levels); vis_ContourSetObject (contour,VIS_COLORMAP,cmap); /* loop through refinement levels */ for(k = 0; k < 3; k++) { vis_VisContextSetRefinement (vc,k); sprintf(text,"Refinement = %d\n",k); /* draw contour types */ for(i = 0; i < 6; i++) { GLWinClear (glwin); GLWinColor (glwin,cname); GLWinText (glwin,xref,text); GLWinText (glwin,xname,isovalname[i]); vis_VisContextSetIsoValType (vc,isovaltype[i]); if(isovaltype[i] == VIS_ISOVALTEXTURE) { GLWinTexture (glwin,256,1,ctexture); } for(j = 0; j < MAX_ELEM; j++) { vis_ContourSetTopology (contour,shap[j],2,0); gatherx (x,numconn[j],conn[j],xe); gathers (s,numconn[j],conn[j],se); vis_ContourCurv (contour,se,xe,VIS_NODATA,NULL); } if(isovaltype[i] == VIS_ISOVALTEXTURE) { GLWinTexture (glwin,0,0,NULL); } GLWinSwap (glwin); sleep(2); } } sleep(5); /* free all objects */ vgl_DrawFunEnd (df); vis_VisContextEnd (vc); vis_LevelsEnd (levels); vis_ColorMapEnd (cmap); vis_ContourEnd (contour); GLWinEnd (glwin); return 0; } /*---------------------------------------------------------------------- Utility functions to gather element vectors and scalars ----------------------------------------------------------------------*/ void gatherx(Vfloat x[][3], Vint npts, Vint con[], Vfloat xe[][3]) { int i, j; for(i = 0; i < npts; i++) { for(j = 0; j < 3; j++) { xe[i][j] = x[con[i]-1][j]; } } } void gathers(Vfloat s[], Vint npts, Vint con[], Vfloat se[]) { int i; for(i = 0; i < npts; i++) { se[i] = s[con[i]-1]; } }
#include "vis/vis.h" #include "glwin.h" void gatherx(Vfloat x[][3], Vint npts, Vint con[], Vfloat xe[][3]); void gathers(Vfloat s[], Vint npts, Vint con[], Vfloat se[]); /* Finite Element Model */ #define MAX_ELEM 2 #define MAX_NODE 10 static Vfloat x[MAX_NODE][3] = { {0.,0.,0.}, {1.,0.,0.}, {2.,0.,0.}, {0.,1.,0.}, {1.,1.,0.}, {0.,0.,1.}, {1.,0.,1.}, {2.,0.,1.}, {0.,1.,1.}, {1.,1.,1.} }; static Vfloat s[MAX_NODE] = { 1., 2., 3.5, 4., 3., 1.2, 2.3, 3.8, 4.4, 3.5 }; static Vint numconn[MAX_ELEM] = { 8, 6 }; static Vint conn[MAX_ELEM][8] = { {1, 2, 5, 4, 6, 7, 10, 9}, {2, 3, 5, 7, 8, 10, 0, 0} }; static Vint shap[MAX_ELEM] = { VIS_SHAPEHEX, VIS_SHAPEWED }; /* Isovalue Types */ static Vint isovaltype[2] = { VIS_ISOVALSURFACE, VIS_ISOVALLINE }; static Vchar *isovalname[2] = { "VIS_ISOVALSURFACE", "VIS_ISOVALLINE" }; static Vfloat xname[3] = { 0., 2., 0. }; static Vfloat cname[3] = { 1., 1., 1. }; /*---------------------------------------------------------------------- Draw Isosurfaces in Elements ----------------------------------------------------------------------*/ int main() { vgl_DrawFun *df; vis_VisContext *vc; vis_Levels *levels; vis_ColorMap *cmap; vis_Threshold *threshold; GLWin *glwin; int i, j, k; Vint nlevels; Vfloat xe[8][3], se[8]; /* create GL device */ glwin = GLWinBegin (); GLWinCreateWindow (glwin,200,200,400,400); GLWinOrtho (glwin,-1.,3.,-1.,3.,-2.,2.); /* create draw function object for GL */ df = vgl_DrawFunBegin (); GLWinDrawFun (glwin,df); /* vis context and set attributes */ vc = vis_VisContextBegin (); /* levels, set twelve evenly spaced levels */ levels = vis_LevelsBegin (); nlevels = 12; vis_LevelsDef (levels,LEVELS_LINEAR,nlevels); vis_LevelsSetMinMax (levels,1.,4.); vis_LevelsGenerate (levels,LEVELS_PADTOP); /* color map */ cmap = vis_ColorMapBegin (); vis_ColorMapRamp (cmap,nlevels,1,COLORMAP_HUE); /* create threshold object and set objects */ threshold = vis_ThresholdBegin (); vis_ThresholdSetObject (threshold,VGL_DRAWFUN,df); vis_ThresholdSetObject (threshold,VIS_VISCONTEXT,vc); vis_ThresholdSetObject (threshold,VIS_LEVELS,levels); vis_ThresholdSetObject (threshold,VIS_COLORMAP,cmap); /* draw threshold types */ for(i = 0; i < 2; i++) { vis_VisContextSetIsoValType (vc,isovaltype[i]); for(k = 0; k < 10; k++) { GLWinClear (glwin); GLWinXfmPush (glwin); GLWinRotate (glwin,k*12.,'y'); GLWinColor (glwin,cname); GLWinText (glwin,xname,isovalname[i]); for(j = 0; j < MAX_ELEM; j++) { vis_ThresholdSetTopology (threshold,shap[j],2,0,0); gatherx (x,numconn[j],conn[j],xe); gathers (s,numconn[j],conn[j],se); vis_ThresholdCurv (threshold,se,xe,VIS_NODATA,NULL); } GLWinXfmPop (glwin); GLWinSwap (glwin); sleep(1); } } sleep(5); /* free all objects */ vgl_DrawFunEnd (df); vis_VisContextEnd (vc); vis_LevelsEnd (levels); vis_ColorMapEnd (cmap); vis_ThresholdEnd (threshold); GLWinEnd (glwin); return 0; } /*---------------------------------------------------------------------- Utility functions to gather element vectors and scalars ----------------------------------------------------------------------*/ void gatherx(Vfloat x[][3], Vint npts, Vint con[], Vfloat xe[][3]) { int i, j; for(i = 0; i < npts; i++) { for(j = 0; j < 3; j++) { xe[i][j] = x[con[i]-1][j]; } } } void gathers(Vfloat s[], Vint npts, Vint con[], Vfloat se[]) { int i; for(i = 0; i < npts; i++) { se[i] = s[con[i]-1]; } }
#include "base/base.h" #include "vgl/vgl.h" #include "vis/vis.h" #include "glwin.h" void gather(Vfloat x[][3], Vint npts, Vint con[], Vfloat xe[][3], Vfloat se[]); /* Finite Element Model */ #define MAX_ELEM 2 #define MAX_NODE 10 /* node coordinates */ static Vfloat x[MAX_NODE][3] = { {0.,0.,0.}, {1.,0.,0.}, {2.,0.,0.}, {0.,1.,0.}, {1.,1.,0.}, {0.,0.,1.}, {1.,0.,1.}, {2.,0.,1.}, {0.,1.,1.}, {1.,1.,1.} }; /* element connectivity */ static Vint numconn[MAX_ELEM] = { 8, 6 }; static Vint conn[MAX_ELEM][8] = { {1, 2, 5, 4, 6, 7, 10, 9}, {2, 3, 5, 7, 8, 10, 0, 0} }; static Vint shap[MAX_ELEM] = { VIS_SHAPEHEX, VIS_SHAPEWED }; /* face data */ static Vint numface[MAX_ELEM] = { 6, 5 }; static Vint numconnface[MAX_ELEM][6] = { {4, 4, 4, 4, 4, 4}, {3, 3, 4, 4, 4, 0} }; /* face connectivity relative to parent element */ static Vint indxface[MAX_ELEM][6][4] = { {{1,4,3,2}, {5,6,7,8}, {1,2,6,5}, {4,8,7,3}, {1,5,8,4}, {2,3,7,6}}, {{1,3,2,0}, {4,5,6,0}, {1,2,5,4}, {1,4,6,3}, {2,3,6,5}, {0,0,0,0}} }; /* colors */ static Vfloat rgb[2][3] = { {1.,1.,1.}, {1.,0.,0.} }; /*---------------------------------------------------------------------- Draw Mesh Section Using Contour and Threshold ----------------------------------------------------------------------*/ int main() { vgl_DrawFun *df; vis_VisContext *vc; vis_Levels *levels; vis_ColorMap *cmap; vis_Contour *contour; vis_Threshold *threshold; GLWin *glwin; int i, j, k, n; Vint nlevels; Vint nfc, ifx[4]; Vfloat xe[8][3], se[8]; /* create GL device */ glwin = GLWinBegin (); GLWinCreateWindow (glwin,200,200,400,400); GLWinOrtho (glwin,-1.,3.,-1.,3.,-2.,2.); /* create draw function object for GL */ df = vgl_DrawFunBegin (); GLWinDrawFun (glwin,df); /* vis context and set attributes */ vc = vis_VisContextBegin (); vis_VisContextSetMapColor (vc,VIS_MAPCOLOR_NONE); /* levels, set twelve evenly spaced levels */ levels = vis_LevelsBegin (); nlevels = 1; vis_LevelsDef (levels,LEVELS_LINEAR,nlevels); vis_LevelsSetValue (levels,1,.5); /* color map */ cmap = vis_ColorMapBegin (); vis_ColorMapSetRGB (cmap,2,1,rgb); /* create contour object and set objects */ contour = vis_ContourBegin (); vis_ContourSetObject (contour,VGL_DRAWFUN,df); vis_ContourSetObject (contour,VIS_VISCONTEXT,vc); vis_ContourSetObject (contour,VIS_LEVELS,levels); vis_ContourSetObject (contour,VIS_COLORMAP,cmap); /* create threshold object and set objects */ threshold = vis_ThresholdBegin (); vis_ThresholdSetObject (threshold,VGL_DRAWFUN,df); vis_ThresholdSetObject (threshold,VIS_VISCONTEXT,vc); vis_ThresholdSetObject (threshold,VIS_LEVELS,levels); vis_ThresholdSetObject (threshold,VIS_COLORMAP,cmap); /* draw mesh section */ for(k = 0; k < 10; k++) { GLWinClear (glwin); GLWinXfmPush (glwin); GLWinRotate (glwin,k*12.,'y'); for(j = 0; j < MAX_ELEM; j++) { /* use threshold to draw cut through element in white */ vis_VisContextSetIsoValType (vc,VIS_ISOVALSURFACE); vis_VisContextSetColor (vc,1); vis_ThresholdSetTopology (threshold,shap[j],2,0,0); gather (x,numconn[j],conn[j],xe,se); vis_ThresholdCurv (threshold,se,xe,VIS_NODATA,NULL); /* use contour to draw cut through element faces in red */ vis_VisContextSetIsoValType (vc,VIS_ISOVALLINE); vis_VisContextSetColor (vc,2); vis_VisContextSetLineWidth (vc,2); /* loop through faces and get face nodes */ for(i = 0; i < numface[j]; i++) { nfc = numconnface[j][i]; for(n = 0; n < nfc; n++) { ifx[n] = conn[j][indxface[j][i][n]-1]; } if(nfc == 3) { vis_ContourSetTopology (contour,SYS_SHAPETRI,2,0); } else { vis_ContourSetTopology (contour,SYS_SHAPEQUAD,2,0); } gather (x,nfc,ifx,xe,se); vis_ContourCurv (contour,se,xe,VIS_NODATA,NULL); } } GLWinXfmPop (glwin); GLWinSwap (glwin); sleep(1); } sleep(5); /* free all objects */ vgl_DrawFunEnd (df); vis_VisContextEnd (vc); vis_LevelsEnd (levels); vis_ColorMapEnd (cmap); vis_ContourEnd (contour); vis_ThresholdEnd (threshold); GLWinEnd (glwin); return 0; } /*---------------------------------------------------------------------- Utility function to gather element data ----------------------------------------------------------------------*/ void gather(Vfloat x[][3], Vint npts, Vint con[], Vfloat xe[][3], Vfloat se[]) { int i, j; for(i = 0; i < npts; i++) { for(j = 0; j < 3; j++) { xe[i][j] = x[con[i]-1][j]; } /* return z coordinate as scalar */ se[i] = x[con[i]-1][2]; } }
The Contour object is configured for normal contour line generation with the addition of a call to vis_ContourSetParami to specify that contour line segment information is meant to be set in the IsoLabel object which has been installed in Contour using vis_ContourSetObject.
Contours are generated on square grid in function generate_contour. The drawing function output is to a VglTools DList object and IsoLabel will accumulate all the contour line segment data and geometry information. The function vis_IsoLabelReset is called to clear any previous contour line segments cached in IsoLabel.
When the contour lines are rendered in function draw_scene, the DList is traversed to draw the contour lines and the function vis_IsoLabelDraw is called to generate contour line labels. The drawing function output from vis_IsoLabel should, in general, be immediately drawn if any graphics view dependent labeling is performed.
#include "base/base.h" #include "vgl/vgl.h" #include "vis/vis.h" static Vfloat rgb[12][3] = { {0.,0.,1.}, {0.,0.2,0.8}, {0.,0.4,0.6}, {0.,0.6,0.4}, {0.,0.8,0.2}, {0.,1.,0.}, {0.2,0.8,0.}, {0.4,0.6,0.},{0.6,0.4,0.},{0.8,0.2,0.}, {1.,0.,0.}, {1.,1.,1.} }; static Vint nlevels = 10; static Vint ndiv = 10; static Vfloat white[3] = {1.,1.,1.}; static void draw_scene(vgl_DrawFun *df, vgl_DList *dlist, vis_IsoLabel *isolabel, vis_VisContext *vc, vgl_RasFont *rasfont, Vint sizetype, Vfloat size, Vint textplane, Vint mapcolor, Vchar title[]) { Vint parami[4]; Vfloat paramf[16], xtitle[3]; /* draw title with default screen oriented font */ vgl_DrawFunRasFontSelect (df,0); xtitle[0] = -2.9; xtitle[1] = 2.7; xtitle[2] = 0.; vgl_DrawFunColor (df,white); vgl_DrawFunText (df,xtitle,title); /* draw contour lines */ vgl_DListCall (dlist); /* pass screen parameters to VisContext */ vgl_DrawFunGetFloat (df,VGL_PROJECTIONMATRIX,paramf); vis_VisContextSetProjMatrix (vc,(Vfloat(*)[4])paramf); vgl_DrawFunGetFloat (df,VGL_MODELVIEWMATRIX,paramf); vis_VisContextSetXfmMatrix (vc,(Vfloat(*)[4])paramf); vgl_DrawFunGetInteger (df,VGL_VIEWPORT,parami); vis_VisContextSetViewport (vc,parami[0],parami[1],parami[2],parami[3]); /* set IsoLabel paramters */ /* turn on user labels when doing world sizing */ vis_VisContextSetSizeType (vc,sizetype); if(sizetype == VIS_SIZEDEVICE) { vis_VisContextSetDeviceSize (vc,(Vint)size); } else { vis_VisContextSetSize (vc,size); vis_IsoLabelSetParami (isolabel,ISOLABEL_LABELUSELEVELS,SYS_ON); } /* set color mapping mode */ vis_VisContextSetMapColor (vc,mapcolor); /* set RasFont text plane mode */ vgl_RasFontSetParami (rasfont,RASFONT_TEXTPLANE,textplane); /* OpenGLDev must reconfigure changed RasFont */ vgl_DrawFunRasFontDefine (df,1,rasfont); vgl_DrawFunRasFontSelect (df,1); vis_IsoLabelSetParami (isolabel,ISOLABEL_TEXTPLANE,textplane); /* draw labels */ vis_IsoLabelDraw (isolabel); } static void generate_contour(vis_Contour *contour) { Vint i, j, n; Vfloat x[4][3], s[4]; /* set all Z coordinates to zero */ x[0][2] = x[1][2] = x[2][2] = x[3][2] = 0.; /* use ContourCurv to draw lines */ vis_ContourSetTopology (contour,SYS_SHAPEQUAD,0,0); for(i = 0; i < ndiv; ++i) { /* set x coordinates */ x[0][0] = -1.8 + i*3.6/ndiv; x[1][0] = -1.8 + (i+1)*3.6/ndiv; x[2][0] = x[1][0]; x[3][0] = x[0][0]; for(j = 0; j < ndiv; ++j) { /* set y coordinates */ x[0][1] = -1.8 + j*3.6/ndiv; x[1][1] = x[0][1]; x[2][1] = -1.8 + (j+1)*3.6/ndiv; x[3][1] = x[2][1]; /* compute distance from center as field to display */ for(n = 0; n < 4; ++n) { s[n] = sqrt(x[n][0]*x[n][0] + x[n][1]*x[n][1]); } vis_ContourCurv (contour,s,x,VIS_NODATA,NULL); } } } /*---------------------------------------------------------------------- Draw Contour Line Labels Using IsoLabel ----------------------------------------------------------------------*/ int main() { #ifdef VKI_WIND_X11 Display *display; int screen; #endif Vint i; Vfloat sizepix; Vchar label[16]; vgl_DrawFun *dfGL, *dfDL; vis_VisContext *vc; vis_ColorMap *cmap; vis_IsoLabel *isolabel; vis_Contour *contour; vis_Levels *levels; vgl_OpenGLDev *ogldev; vgl_RasFont *rasfont; vgl_DList *dlist; #ifdef VKI_WIND_X11 /* open X display */ display = XOpenDisplay (0); screen = DefaultScreen (display); vgl_OpenGLDevConnectX (display,screen); #endif #ifdef VKI_WIND_WIN32 vgl_OpenGLDevConnectWIN (); #endif /* create GL device */ ogldev = vgl_OpenGLDevBegin (); /* create draw function object for GL */ dfGL = vgl_DrawFunBegin (); vgl_OpenGLDevDrawFun (ogldev,dfGL); vgl_DrawFunPositionWindow (dfGL,200,200,800,800); vgl_DrawFunOpenWindow (dfGL,"Example 10cvgl"); vgl_DrawFunProjOrtho (dfGL,-3.,3.,-3.,3.,-1.,1.); /* * IsoLabel always uses VGL_BOTTOM, but it must * know what the VGL_TEXTANCHORMODE has been set to * so it can compensate for it */ vgl_DrawFunSetMode (dfGL,VGL_TEXTANCHORMODE,VGL_BOTTOMLEFT); /* create draw function object for DList */ dlist = vgl_DListBegin (); dfDL = vgl_DrawFunBegin (); vgl_DListDrawFun (dlist,dfDL); vgl_DListSetObject (dlist,VGL_DRAWFUN,(Vobject*)dfGL); /* create objects */ vc = vis_VisContextBegin (); cmap = vis_ColorMapBegin (); levels = vis_LevelsBegin (); isolabel = vis_IsoLabelBegin (); contour = vis_ContourBegin (); rasfont = vgl_RasFontBegin (); /* configure ColorMap */ vis_ColorMapSetType (cmap,COLORMAP_TRUECOLOR); vis_ColorMapSetRGB (cmap,12,0,rgb); /* configure Levels */ vis_LevelsDef (levels,LEVELS_LINEAR,nlevels); vis_LevelsSetMinMax (levels,0.,3.); vis_LevelsGenerate (levels,LEVELS_PADENDS); /* user defined labels at levels */ for(i = 1; i <= nlevels; i++) { sprintf (label,"level %d",i); vis_LevelsSetLabel (levels,i,label); } /* configure Contour */ vis_ContourSetObject (contour,VGL_DRAWFUN,dfDL); vis_ContourSetObject (contour,VIS_ISOLABEL,isolabel); vis_ContourSetObject (contour,VIS_VISCONTEXT,vc); vis_ContourSetObject (contour,VIS_COLORMAP,cmap); vis_ContourSetObject (contour,VIS_LEVELS,levels); /* tell Contour to generate data for IsoLabel */ vis_ContourSetParami (contour,CONTOUR_ISOVALDATA,SYS_ON); /* configure IsoLabel */ vis_IsoLabelSetObject (isolabel,VIS_VISCONTEXT,vc); vis_IsoLabelSetObject (isolabel,VIS_COLORMAP,cmap); vis_IsoLabelSetObject (isolabel,VIS_LEVELS,levels); vis_IsoLabelSetObject (isolabel,VGL_DRAWFUN,dfGL); vis_IsoLabelSetParami (isolabel,ISOLABEL_TEXTPLANE,SYS_ON); /* add labels to every other level */ vis_IsoLabelSetParami (isolabel,ISOLABEL_LINEFREQUENCY,2); /* use numeric values, not pre-defined string labels */ vis_IsoLabelSetParami (isolabel,ISOLABEL_LABELUSELEVELS,SYS_OFF); /* tolerance to merge lines from Contour */ vis_VisContextSetDistTol (vc,0.01); /* segment curvature tolerance to skip labeling */ vis_IsoLabelSetParamf (isolabel,ISOLABEL_CURVFRAC,0.05); /* flag to not allow overlap of labels */ vis_IsoLabelSetParami (isolabel,ISOLABEL_OVERLAP,SYS_OFF); /* configure RasFont */ vgl_RasFontLoad (rasfont,RASFONT_QUALITY9X13); vgl_RasFontSetParami (rasfont,RASFONT_DEVICESIZE,SYS_ON); vgl_DrawFunRasFontDefine (dfGL,1,rasfont); vgl_DrawFunRasFontSelect (dfGL,1); /* configure VisContext */ /* white constant color */ vis_VisContextSetColor (vc,11); /* draw dot where label is positioned */ vis_VisContextSetSpot (vc,SYS_ON); vis_VisContextSetPointSize (vc,4); /* set TEXTANCHORMODE as used by DrawFun */ vis_VisContextSetPosition (vc,VGL_BOTTOMLEFT); /* specify floating point format for label */ vis_VisContextSetFormat (vc,VIS_FMFORMAT); /* space labels based on device (pixels) distance */ vis_VisContextSetSizeType (vc,VIS_SIZEDEVICE); /* space labels at approximately 200 pixels on lines */ vis_VisContextSetDeviceSize (vc,200); /* offset label 3 pixels away from lines */ vis_VisContextSetDeviceOffset (vc,0,3); /* always orient labels so they read left to right */ vis_VisContextSetFlags (vc,VIS_BACKPLANEFLIP); /* specify raster font character sizes */ vis_VisContextSetTextBox (vc,9,13); /* for Contour object, generate lines */ vis_VisContextSetIsoValType (vc,VIS_ISOVALLINE); vis_VisContextSetMapColor (vc,VIS_MAPCOLOR_SMOOTH); /* generate contour */ vis_IsoLabelReset (isolabel); generate_contour (contour); /* draw */ /* vary the device size */ for(i = 1; i <= 5; i++) { vgl_DrawFunClear (dfGL); sizepix = i*20.; draw_scene (dfGL,dlist,isolabel,vc,rasfont, VIS_SIZEDEVICE,sizepix,SYS_ON,VIS_MAPCOLOR_SMOOTH, "SIZE=DEVICE, TEXTPLANE=SYS_ON, MAPCOLOR=SMOOTH"); vgl_DrawFunSwap (dfGL); vgl_DrawFunDelay (dfGL,2.); } /* do not output oriented labels */ vgl_DrawFunClear (dfGL); draw_scene (dfGL,dlist,isolabel,vc,rasfont, VIS_SIZEDEVICE,200.,SYS_OFF,VIS_MAPCOLOR_SMOOTH, "SIZE=DEVICE, TEXTPLANE=SYS_OFF, MAPCOLOR=SMOOTH"); vgl_DrawFunSwap (dfGL); vgl_DrawFunDelay (dfGL,5.); /* constant color, white, labels */ vgl_DrawFunClear (dfGL); draw_scene (dfGL,dlist,isolabel,vc,rasfont, VIS_SIZEDEVICE,200.,SYS_OFF,VIS_MAPCOLOR_NONE, "SIZE=DEVICE, TEXTPLANE=SYS_OFF, MAPCOLOR=NONE"); vgl_DrawFunSwap (dfGL); vgl_DrawFunDelay (dfGL,5.); /* world coordinate spacing of oriented labels */ vgl_DrawFunClear (dfGL); draw_scene (dfGL,dlist,isolabel,vc,rasfont, VIS_SIZEWORLD,0.5,SYS_ON,VIS_MAPCOLOR_SMOOTH, "SIZE=WORLD, TEXTPLANE=SYS_ON, MAPCOLOR=SMOOTH"); vgl_DrawFunSwap (dfGL); vgl_DrawFunDelay (dfGL,5.); /* close window */ vgl_DrawFunCloseWindow (dfGL); /* disconnect */ vgl_OpenGLDevDisconnect (); #ifdef VKI_WIND_X11 XCloseDisplay (display); #endif /* free all objects */ vgl_RasFontEnd (rasfont); vis_ContourEnd (contour); vis_IsoLabelEnd (isolabel); vis_LevelsEnd (levels); vis_ColorMapEnd (cmap); vis_VisContextEnd (vc); vgl_DrawFunEnd (dfGL); vgl_DrawFunEnd (dfDL); vgl_DListEnd (dlist); vgl_OpenGLDevEnd (ogldev); return 0; }
The scalar marker types display variations in marker type and color mapping using the scalar VisContext object. The vector markers display variations in vector type, color mapping and size mapping. Component vectors are drawn first, then resultants. Tensor markers are a composite of vectors and a tensorbox type. Therefore the display of tensor markers can be changed by altering both the vector and tensor VisContext attribute objects.
Note that the vis_MarkTensorCompute function is used to annotate the ends of the vectors in the tensor marker with component or principal values. Component tensors are drawn first then the same tensors are drawn in their principal directions and maximum shear directions.
#include "base/base.h" #include "vgl/vgl.h" #include "vis/vis.h" #include "glwin.h" static Vfloat xpt[3][3] = { {-1.,0.,0.}, {0.,0.,0.}, {1.,0.,0.} }; static Vfloat sca = { -.6 }; static Vfloat vec[3] = { .3,-.6, 1. }; static Vfloat ten[6] = { .3,-.6, 1., .6, .2,-.4 }; static Vfloat xtex[3] = { -1., 1.5, 0. }; static Vfloat ctex[3] = { 1., 1., 1. }; static Vfloat rgb[7][3] = { {.5,.5,.5}, {1.,0.,0.}, {0.,1.,0.}, {0.,0.,1.}, {0.,1.,1.}, {1.,0.,1.}, {1.,1.,0.} }; /*---------------------------------------------------------------------- Display a Scalar, Vector and Tensor in 3 Ways ----------------------------------------------------------------------*/ int main() { vgl_DrawFun *df; vis_VisContext *vcsca, *vcvec, *vcten; vis_Levels *levels; vis_ColorMap *cmap; vis_Mark *mark; GLWin *glwin; int i, j, k; Vint nlevels; Vfloat van[6], xan[6][2][3]; Vchar stg[16]; /* create GL device */ glwin = GLWinBegin (); GLWinCreateWindow (glwin,200,200,400,400); GLWinOrtho (glwin,-2.,2.,-2.,2.,-2.,2.); /* create draw function object for GL */ df = vgl_DrawFunBegin (); GLWinDrawFun (glwin,df); /* scalar viscontext and set attributes */ vcsca = vis_VisContextBegin (); vis_VisContextSetColor (vcsca,4); vis_VisContextSetRefinement (vcsca,2); /* vector viscontext and set attributes */ vcvec = vis_VisContextBegin (); vis_VisContextSetFlags (vcvec,VIS_VECTORTAIL | VIS_VECTORTAILREGISTER); vis_VisContextSetMapSize (vcvec,VIS_ON); vis_VisContextSetXYZColor (vcvec,4,5,6); /* tensor viscontext and set attributes */ vcten = vis_VisContextBegin (); vis_VisContextSetFlags (vcten,VIS_TENSORBOX | VIS_TENSORDIRECT | VIS_TENSORSHEAR); vis_VisContextSetMapSize (vcten,VIS_ON); vis_VisContextSetXYZColor (vcten,4,5,6); vis_VisContextSetRefinement (vcten,1); /* levels, set three evenly spaced levels */ levels = vis_LevelsBegin (); nlevels = 6; vis_LevelsDef (levels,LEVELS_LINEAR,nlevels); vis_LevelsSetMinMax (levels,-1.,1.); vis_LevelsGenerate (levels,LEVELS_PADNONE); /* color map */ cmap = vis_ColorMapBegin (); vis_ColorMapSetType (cmap,COLORMAP_TRUECOLOR); vis_ColorMapSetRGB (cmap,7,0,rgb); /* create mark object and set objects */ mark = vis_MarkBegin (); vis_MarkSetObject (mark,VGL_DRAWFUN,df); vis_MarkSetObject (mark,VIS_VISCONTEXT_SCALAR,vcsca); vis_MarkSetObject (mark,VIS_VISCONTEXT_VECTOR,vcvec); vis_MarkSetObject (mark,VIS_VISCONTEXT_TENSOR,vcten); vis_MarkSetObject (mark,VIS_LEVELS,levels); vis_MarkSetObject (mark,VIS_COLORMAP,cmap); /* draw scalars */ for(i = 0; i < 8; i++) { GLWinClear (glwin); GLWinColor (glwin,ctex); GLWinText (glwin,xtex,"Scalar"); GLWinXfmPush (glwin); GLWinRotate (glwin,i*8.,'x'); GLWinRotate (glwin,i*4.,'y'); /* 3D spherical type scalar, mapped to color */ vis_VisContextSetMarkerType (vcsca,VIS_SPHERE); vis_VisContextSetMapColor (vcsca,VIS_ON); vis_MarkScalar (mark,1,&sca,(Vfloat(*)[3])xpt[0]); /* 2D line type scalar, not mapped to color */ vis_VisContextSetMarkerType (vcsca,VIS_HOURGLASS); vis_VisContextSetMapColor (vcsca,VIS_OFF); vis_MarkScalar (mark,1,&sca,(Vfloat(*)[3])xpt[1]); /* 2D point type scalar, mapped to color */ vis_VisContextSetMarkerType (vcsca,VIS_POINT4); vis_VisContextSetMapColor (vcsca,VIS_ON); vis_MarkScalar (mark,1,&sca,(Vfloat(*)[3])xpt[2]); GLWinXfmPop (glwin); GLWinSwap (glwin); sleep(1); } sleep(2); /* draw vectors */ for(j = 0; j < 2; j++) { for(i = 0; i < 8; i++) { GLWinClear (glwin); GLWinColor (glwin,ctex); if(j) { vis_VisContextSetComponent (vcvec,VIS_COMPONENT_PRINCIPAL); GLWinText (glwin,xtex,"Vector Resultants"); } else { vis_VisContextSetComponent (vcvec,VIS_COMPONENT_BASIC); GLWinText (glwin,xtex,"Vector Components"); } GLWinXfmPush (glwin); GLWinRotate (glwin,i*8.,'x'); GLWinRotate (glwin,i*4.,'y'); /* 3D cylindrical type vector, mapped to color */ vis_VisContextSetVectorType (vcvec,VIS_VECTORCYLINDER); vis_VisContextSetMapColor (vcvec,VIS_ON); vis_MarkVector (mark,1,(Vfloat(*)[3])vec,(Vfloat(*)[3])xpt[0]); /* 2D line type vector, not mapped to color */ vis_VisContextSetVectorType (vcvec,VIS_VECTORLINE); vis_VisContextSetMapColor (vcvec,VIS_OFF); vis_MarkVector (mark,1,(Vfloat(*)[3])vec,(Vfloat(*)[3])xpt[1]); /* 3D polygon head, 2D line tail vector, mapped to color */ vis_VisContextSetVectorType (vcvec,VIS_VECTORUMBRELLA); vis_VisContextSetMapSize (vcvec,VIS_OFF); vis_VisContextSetSize (vcvec,.6); vis_VisContextSetMapColor (vcvec,VIS_ON); vis_MarkVector (mark,1,(Vfloat(*)[3])vec,(Vfloat(*)[3])xpt[2]); vis_VisContextSetMapSize (vcvec,VIS_ON); vis_VisContextSetSize (vcvec,1.); GLWinXfmPop (glwin); GLWinSwap (glwin); sleep(1); } sleep(1); } sleep(2); /* draw tensors */ for(j = 0; j < 3; j++) { for(i = 0; i < 8; i++) { GLWinClear (glwin); GLWinColor (glwin,ctex); if(j == 2) { vis_VisContextSetComponent (vcten,VIS_COMPONENT_MAXSHEAR); GLWinText (glwin,xtex,"Tensor Max Shear"); } else if(j == 1) { vis_VisContextSetComponent (vcten,VIS_COMPONENT_PRINCIPAL); GLWinText (glwin,xtex,"Tensor Principals"); } else { vis_VisContextSetComponent (vcten,VIS_COMPONENT_BASIC); GLWinText (glwin,xtex,"Tensor Components"); } GLWinXfmPush (glwin); GLWinRotate (glwin,i*8.,'x'); GLWinRotate (glwin,i*4.,'y'); /* 3D ellipsoidal tensor, mapped to color */ vis_VisContextSetVectorType (vcvec,VIS_VECTORCYLINDER); vis_VisContextSetTensorType (vcten,VIS_TENSORELLIPSOID); vis_VisContextSetMapColor (vcten,VIS_ON); vis_MarkTensor (mark,1,(Vfloat(*)[6])ten,(Vfloat(*)[3])xpt[0]); /* 3D cube tensor, not mapped to color */ vis_VisContextSetVectorType (vcvec,VIS_VECTORLINE); vis_VisContextSetTensorType (vcten,VIS_TENSORCUBE); vis_VisContextSetMapColor (vcten,VIS_OFF); vis_VisContextSetSize (vcten,.6); vis_VisContextSetXYZColor (vcten,0,0,0); vis_MarkTensor (mark,1,(Vfloat(*)[6])ten,(Vfloat(*)[3])xpt[1]); vis_VisContextSetMapSize (vcten,VIS_ON); vis_VisContextSetSize (vcten,1.); vis_VisContextSetXYZColor (vcten,4,5,6); /* 2D crows feet tensor, mapped to color */ vis_VisContextSetVectorType (vcvec,VIS_VECTORUMBRELLA); vis_VisContextSetTensorType (vcten,VIS_TENSORCROWSFEET); vis_VisContextSetMapColor (vcten,VIS_ON); vis_VisContextSetMapSize (vcvec,VIS_OFF); vis_VisContextSetSize (vcvec,.6); vis_MarkTensor (mark,1,(Vfloat(*)[6])ten,(Vfloat(*)[3])xpt[2]); vis_MarkTensorCompute (mark,ten,xpt[2],van,xan); vis_VisContextSetMapSize (vcvec,VIS_ON); vis_VisContextSetSize (vcvec,1.); /* annotate */ GLWinColor (glwin,ctex); for(k = 0; k < 6; k++) { if(van[k] != 0.) { sprintf(stg,"%g",van[k]); GLWinText (glwin,xan[k][0],stg); } } GLWinXfmPop (glwin); GLWinSwap (glwin); sleep(1); } sleep(1); } sleep(2); /* free all objects */ vgl_DrawFunEnd (df); vis_VisContextEnd (vcsca); vis_VisContextEnd (vcvec); vis_VisContextEnd (vcten); vis_LevelsEnd (levels); vis_ColorMapEnd (cmap); vis_MarkEnd (mark); GLWinEnd (glwin); return 0; }
The distributed pressure load is drawn with vectors pointing in the direction of the pressure load at the face nodes and a contoured surface showing the magnitude and distribution of the pressure. It is important that the vis_VisContextSetSize function be used to indicate the size of the markers at their maximum magnitude as set in the Levels object. The function vis_FaceComputeDist is used to compute the equivalent nodal loads for the distributed pressure. The equivalent nodal load vectors are drawn. The face is a parabolic Serendipity topology, note that the equivalent nodal loads are somewhat counter intuitive. The function vis_FaceConvertDist is then called to convert the equivalent nodal loads to a distributed traction. The recovered tractions are drawn and are identical to the original distributed pressure vectors.
The distributed moment load is drawn with round vectors pointing in the direction of the moment load at the edge nodes and a constant colored surface showing the magnitude and distribution of the moment. The load surface is decomposed into 12 strips, each of which is drawn as a 3 by 2 point face.
#include "base/base.h" #include "vgl/vgl.h" #include "vis/vis.h" static Vfloat xquad[8][3] = { {-1.,-1.,0.},{1.,-1.,0.},{1.,1.,0.},{-1.,1.,0.}, {0.,-1.1,0.},{1.,0.,0.1},{0.,1.,0.},{-1.,0.,0.2} }; static Vfloat xline[3][3] = { {-1.,-1.,0.},{0.,-1.1,0.},{1.,-1.,0.} }; static Vfloat xtitle[3] = {-1.5,1.5,0.}; /* Red,Green,Blue components of entity Colormap */ static Vfloat gray[3] = {.6,.6,.6 }; static Vfloat white[3] = { 1.,1.,1.}; static Vfloat lightblue[3] = { .5,.5,1.}; /* scalar element node face pressures */ static Vfloat pres[8] = { 1., 2., 7., 4., 1.5, 3.5, 5.5, 2.5 }; /* scalar element node line moments */ static Vfloat moment[3] = {1., 3., 2.5}; /*---------------------------------------------------------------------- Draw Distributed Loads ----------------------------------------------------------------------*/ int main() { #ifdef VKI_WIND_X11 Display *display; int screen; #endif vis_Face *face; vis_Edge *edge; vis_Contour *contour; vis_Mark *mark; vis_VisContext *vc, *vccontour, *vcmark; vis_Levels *levels; vis_ColorMap *cmapiso, *cmap; vis_TransMap *tmap; vgl_DrawFun *df; vgl_OpenGLDev *ogldev; vgl_Xfm *xfm; Vint i, j, k, n; Vfloat tm[4][4], cl[3], xl[3]; Vfloat vec[8][3], norm[8][3], xo[8][3], sc, tang[3][3]; Vfloat enl[8][3], vcl[8][3]; Vfloat rx[3][3], ry[3][3], d[3], ang, xv[3], xe[6][3], ve[6][3]; Vfloat trans; Vint flag; Vint nlevels; /* connect to window system */ #ifdef VKI_WIND_X11 if(vgl_OpenGLDevTestX (&flag),flag == 0) { printf("OpenGL not enabled, exiting\n"); return 1; } display = XOpenDisplay (0); screen = DefaultScreen (display); vgl_OpenGLDevConnectX (display,screen); #endif #ifdef VKI_WIND_WIN32 if(vgl_OpenGLDevTestWIN (&flag),flag == 0) { printf("OpenGL not enabled, exiting\n"); return 1; } vgl_OpenGLDevConnectWIN (); #endif /* create OpenGL device */ ogldev = vgl_OpenGLDevBegin (); df = vgl_DrawFunBegin (); vgl_OpenGLDevDrawFun (ogldev,df); vgl_DrawFunPositionWindow (df,200,200,600,600); vgl_DrawFunOpenWindow (df,"Example 11avgl"); vgl_DrawFunProjOrtho (df,-2.0,2.0,-2.0,2.0,-10.,10.); vgl_DrawFunSetMode (df,VGL_ZBUFFERMODE,VGL_ON); vgl_DrawFunSetMode (df,VGL_LIGHTMODE,VGL_ON); cl[0] = .7; cl[1] = .7; cl[2] = .7; xl[0] = 0.; xl[1] = 0.; xl[2] = 0.; vgl_DrawFunLight (df,0,VGL_LIGHT_AMBIENT,cl,xl); cl[0] = .5; cl[1] = .5; cl[2] = .5; xl[0] = 1.; xl[1] = 1.; xl[2] = 1.; vgl_DrawFunLight (df,1,VGL_LIGHT_DISTANT,cl,xl); /* create transformation object */ xfm = vgl_XfmBegin (); /* edge/face vis context */ vc = vis_VisContextBegin (); vis_VisContextSetRefinement (vc,2); vis_VisContextSetShade (vc,VIS_VERTEXSHADE); /* edge/face color map */ cmap = vis_ColorMapBegin (); vis_ColorMapSetType (cmap,COLORMAP_TRUECOLOR); vis_ColorMapSetRGB (cmap,1,1,&gray); vis_ColorMapSetRGB (cmap,1,2,&white); vis_ColorMapSetRGB (cmap,1,3,&lightblue); /* transparency map */ trans = .5; tmap = vis_TransMapBegin (); vis_TransMapSetType (tmap,TRANSMAP_FACTOR); vis_TransMapSetTrans (tmap,1,1,&trans); /* create face object and set objects */ face = vis_FaceBegin (); vis_FaceSetObject (face,VGL_DRAWFUN,df); vis_FaceSetObject (face,VIS_VISCONTEXT,vc); vis_FaceSetObject (face,VIS_COLORMAP,cmap); vis_FaceSetObject (face,VIS_TRANSMAP,tmap); /* create edge object and set objects */ edge = vis_EdgeBegin (); vis_EdgeSetObject (edge,VGL_DRAWFUN,df); vis_EdgeSetObject (edge,VIS_VISCONTEXT,vc); vis_EdgeSetObject (edge,VIS_COLORMAP,cmap); /* define levels */ nlevels = 12; levels = vis_LevelsBegin (); vis_LevelsDef (levels,LEVELS_LINEAR,nlevels); /* generate load color maps */ cmapiso = vis_ColorMapBegin (); vis_ColorMapSetType (cmapiso,COLORMAP_TRUECOLOR); vis_ColorMapRamp (cmapiso,nlevels,1,COLORMAP_HUE); /* mark vis context */ vcmark = vis_VisContextBegin (); vis_VisContextSetMapSize (vcmark,SYS_ON); vis_VisContextSetSize (vcmark,1.); vis_VisContextSetMapColor (vcmark,VIS_MAPCOLOR_SMOOTH); /* distributed load vectors */ mark = vis_MarkBegin (); vis_MarkSetObject (mark,VGL_DRAWFUN,df); vis_MarkSetObject (mark,VIS_VISCONTEXT,vcmark); vis_MarkSetObject (mark,VIS_LEVELS,levels); vis_MarkSetObject (mark,VIS_COLORMAP,cmapiso); /* setup contour object */ vccontour = vis_VisContextBegin (); vis_VisContextSetIsoValType (vccontour,VIS_ISOVALFRINGE); vis_VisContextSetRefinement (vccontour,2); vis_VisContextSetShade (vccontour,VIS_VERTEXSHADE); vis_VisContextSetTrans (vccontour,1); contour = vis_ContourBegin (); vis_ContourSetObject (contour,VGL_DRAWFUN,df); vis_ContourSetObject (contour,VIS_VISCONTEXT,vccontour); vis_ContourSetObject (contour,VIS_LEVELS,levels); vis_ContourSetObject (contour,VIS_COLORMAP,cmapiso); vis_ContourSetObject (contour,VIS_TRANSMAP,tmap); /* draw pressure */ vis_LevelsSetMinMax (levels,0.,7.); vis_LevelsGenerate (levels,LEVELS_PADTOP); for(i = 1; i <= 20; i++) { vgl_DrawFunClear (df); vgl_DrawFunColor(df,white); vgl_DrawFunText(df,xtitle,"Distributed pressure surface"); vgl_DrawFunXfmPush (df); vgl_XfmRotate (xfm,-(i-1)*8.*3.14/180.,XFM_YAXIS); vgl_XfmGetMatrix (xfm,tm); vgl_DrawFunXfmLoad (df,tm); /* draw element face - gray, opaque */ vis_VisContextSetColor (vc,1); vis_VisContextSetTrans (vc,0); vis_FaceSetTopology (face,SYS_SHAPEQUAD,3,0); vis_FaceCurv (face,xquad,VIS_NODATA,NULL); /* compute pressure sized normal to surface */ vis_FaceComputeNorm (face,xquad,norm); for(n = 0; n < 8; n++) { vec[n][0] = -pres[n]*norm[n][0]; vec[n][1] = -pres[n]*norm[n][1]; vec[n][2] = -pres[n]*norm[n][2]; } /* draw vectors at face nodes */ vis_VisContextSetRefinement (vcmark,1); vis_VisContextSetVectorType (vcmark,VIS_VECTORUMBRELLA); vis_VisContextSetFlags (vcmark,VIS_VECTORTAIL); vis_MarkVector (mark,8,vec,xquad); /* draw pressure colored offset face */ /* compute locations of vector tails for pressure face */ for(n = 0; n < 8; n++) { vis_MarkVectorCompute (mark,vec[n],xquad[n],&sc,&xo[n]); } vis_VisContextTouch (vccontour); vis_ContourSetTopology (contour,SYS_SHAPEQUAD,3,0); vis_ContourCurv (contour,pres,xo,VIS_VERTEXDATA,norm); vgl_DrawFunSwap (df); vgl_DrawFunDelay (df,1.); /* show equivalent nodal loads on eighth frame */ if(i == 8) { vgl_DrawFunClear (df); vgl_DrawFunColor(df,white); vgl_DrawFunText(df,xtitle,"Equivalent nodal loads"); vis_VisContextTouch (vc); vis_FaceCurv (face,xquad,VIS_NODATA,NULL); vis_FaceComputeDist (face,xquad,3,(Vfloat*)vec,(Vfloat*)enl); vis_MarkVector (mark,8,enl,xquad); vgl_DrawFunSwap (df); vgl_DrawFunDelay (df,2.); } /* show and recover original tractions on eighth frame */ if(i == 8) { vgl_DrawFunClear (df); vgl_DrawFunColor(df,white); vgl_DrawFunText(df,xtitle,"Recover original tractions"); vis_VisContextTouch (vc); vis_FaceCurv (face,xquad,VIS_NODATA,NULL); vis_FaceConvertDist (face,xquad,3,(Vfloat*)enl,(Vfloat*)vcl); vis_MarkVector (mark,8,vcl,xquad); vgl_DrawFunSwap (df); vgl_DrawFunDelay (df,2.); } vgl_DrawFunXfmPop (df); } /* draw edge moment */ vis_LevelsSetMinMax (levels,0.,3.); vis_LevelsGenerate (levels,LEVELS_PADTOP); for(i = 0; i < 20; i++) { vgl_DrawFunClear (df); vgl_DrawFunColor(df,white); vgl_DrawFunText(df,xtitle,"Distributed edge moment"); vgl_DrawFunXfmPush (df); vgl_XfmRotate (xfm,-i*8.*3.14/180.,XFM_YAXIS); vgl_XfmGetMatrix (xfm,tm); vgl_DrawFunXfmLoad (df,tm); /* draw face */ vis_VisContextSetColor (vc,1); vis_VisContextSetTrans (vc,0); vis_FaceSetTopology (face,SYS_SHAPEQUAD,3,0); vis_FaceCurv (face,xquad,VIS_NODATA,NULL); /* draw edge */ vis_VisContextSetColor (vc,2); vis_VisContextSetLineWidth (vc,2); vis_EdgeSetTopology (edge,SYS_SHAPELINE,3); vis_EdgeCurv (edge,xline); /* compute tangent to edge and scale vector by moment */ vis_EdgeComputeTang (edge,xline,tang); for(n = 0; n < 3; n++) { vec[n][0] = tang[n][0]*moment[n]; vec[n][1] = tang[n][1]*moment[n]; vec[n][2] = tang[n][2]*moment[n]; } /* draw round moment vectors along edge */ vis_VisContextSetRefinement (vcmark,2); vis_VisContextSetVectorType (vcmark,VIS_VECTORCYLINDER); vis_VisContextSetFlags (vcmark,VIS_VECTORTAIL|VIS_VECTORROUND); vis_MarkVector (mark,3,vec,xline); /* connect moment arrows with transparent surface */ /* compute local x', y' directions perpendicular to edge and marker radius */ for(n = 0; n < 3; n++) { vis_MarkVectorCompute (mark,vec[n],xline[n],&sc,&xo[n]); rx[n][0] = xo[n][0] - xline[n][0]; rx[n][1] = xo[n][1] - xline[n][1]; rx[n][2] = xo[n][2] - xline[n][2]; ry[n][0] = tang[n][1]*rx[n][2] - tang[n][2]*rx[n][1]; ry[n][1] = tang[n][2]*rx[n][0] - tang[n][0]*rx[n][2]; ry[n][2] = tang[n][0]*rx[n][1] - tang[n][1]*rx[n][0]; d[n] = sqrt(rx[n][0]*rx[n][0]+rx[n][1]*rx[n][1]+rx[n][2]*rx[n][2]); } /* draw surface - lightblue, transparent */ vis_VisContextSetColor (vc,3); vis_VisContextSetTrans (vc,1); for(j = 0; j < 12; j++) { for(k = 0; k < 2; k++) { ang = 2.*(j+k)/12.*3.14159; xv[0] = cos(ang); xv[1] = sin(ang); xv[2] = 0.; /* compute coordinates and normals of a 3 by 2 strip */ for(n = 0; n < 3; n++) { xe[n+3*k][0] = xline[n][0] + xv[0]*rx[n][0]+xv[1]*ry[n][0]; xe[n+3*k][1] = xline[n][1] + xv[0]*rx[n][1]+xv[1]*ry[n][1]; xe[n+3*k][2] = xline[n][2] + xv[0]*rx[n][2]+xv[1]*ry[n][2]; ve[n+3*k][0] = (xe[n+3*k][0]-xline[n][0])/d[n]; ve[n+3*k][1] = (xe[n+3*k][1]-xline[n][1])/d[n]; ve[n+3*k][2] = (xe[n+3*k][2]-xline[n][2])/d[n]; } } /* draw strip with face object */ vis_FaceSetTopology (face,SYS_SHAPEQUAD,3,2); vis_FaceCurv (face,xe,VIS_VERTEXDATA,ve); } vgl_DrawFunXfmPop (df); vgl_DrawFunSwap (df); vgl_DrawFunDelay (df,1.); } vgl_DrawFunDelay (df,5.); /* free all objects */ vgl_DrawFunEnd (df); vgl_OpenGLDevEnd (ogldev); vgl_XfmEnd (xfm); vis_VisContextEnd (vc); vis_ColorMapEnd (cmap); vis_TransMapEnd (tmap); vis_FaceEnd (face); vis_EdgeEnd (edge); vis_LevelsEnd (levels); vis_ColorMapEnd (cmapiso); vis_MarkEnd (mark); vis_VisContextEnd (vcmark); vis_VisContextEnd (vccontour); vis_ContourEnd (contour); /* disconnect from window system */ vgl_OpenGLDevDisconnect (); #ifdef VKI_WIND_X11 XCloseDisplay (display); #endif return 0; }
#include "base/base.h" #include "vgl/vgl.h" #include "vis/vis.h" #include "glwin.h" static Vfloat rgb[8][3] = { {.8,.8,.8}, {1.,0.,0.}, {0.,1.,0.}, {0.,0.,1.}, {0.,1.,1.}, {1.,0.,1.}, {1.,1.,0.}, {1.,1.,1.} }; static Vfloat xtex[3] = { -.5, 3.5, 0. }; static Vfloat ctex[3] = { 1., 1., 1. }; /*---------------------------------------------------------------------- Draw triads ----------------------------------------------------------------------*/ int main() { vgl_DrawFun *df; vis_VisContext *vc; vis_ColorMap *cmap; vis_Triad *triad; GLWin *glwin; int i; Vfloat x[3], tm[3][3]; /* create GL device */ glwin = GLWinBegin (); GLWinCreateWindow (glwin,200,200,700,500); GLWinOrtho (glwin,-1.,6.,-1.,4.,-4.,4.); /* create draw function object for GL */ df = vgl_DrawFunBegin (); GLWinDrawFun (glwin,df); vc = vis_VisContextBegin (); vis_VisContextSetLineWidth (vc,2); vis_VisContextSetMinorColor (vc,0); vis_VisContextSetSize (vc,1.); vis_VisContextSetMinorSize (vc,.5); vis_VisContextSetColor (vc,7); vis_VisContextSetXYZColor (vc,1,2,3); vis_VisContextSetABCColor (vc,7,7,7); vis_VisContextSetTrans (vc,1); /* color map */ cmap = vis_ColorMapBegin (); vis_ColorMapSetType (cmap,COLORMAP_TRUECOLOR); vis_ColorMapSetRGB (cmap,8,0,rgb); /* create triad object and set objects */ triad = vis_TriadBegin (); vis_TriadSetObject (triad,VGL_DRAWFUN,df); vis_TriadSetObject (triad,VIS_VISCONTEXT,vc); vis_TriadSetObject (triad,VIS_COLORMAP,cmap); /* set triad orientation to the global system */ tm[0][0] = 1.; tm[0][1] = 0.; tm[0][2] = 0.; tm[1][0] = 0.; tm[1][1] = 1.; tm[1][2] = 0.; tm[2][0] = 0.; tm[2][1] = 0.; tm[2][2] = 1.; /* use line vectors and no detail */ vis_VisContextSetVectorType (vc,VIS_VECTORLINE); vis_TriadSetParami (triad,TRIAD_DETAIL,VIS_OFF); /* draw basic triads */ for(i = 0; i < 8; i++) { GLWinClear (glwin); GLWinColor (glwin,ctex); GLWinText (glwin,xtex,"Basic Triads"); GLWinXfmPush (glwin); GLWinRotate (glwin,i*8.,'x'); GLWinRotate (glwin,i*4.,'y'); x[0] = 0.; x[1] = 0.; x[2] = 0.; vis_TriadDraw (triad,SYS_CARTESIAN,x,tm); x[0] = 2.; x[1] = 0.; x[2] = 0.; vis_TriadDraw (triad,SYS_CYLINDRICAL,x,tm); x[0] = 4.; x[1] = 0.; x[2] = 0.; vis_TriadDraw (triad,SYS_CYLINDRICAL_ALT,x,tm); x[0] = 0.; x[1] = 2.; x[2] = 0.; vis_TriadDraw (triad,SYS_SPHERICAL,x,tm); x[0] = 2.; x[1] = 2.; x[2] = 0.; vis_TriadDraw (triad,SYS_SPHERICAL_ALT,x,tm); x[0] = 4.; x[1] = 2.; x[2] = 0.; vis_TriadDraw (triad,SYS_TOROIDAL,x,tm); GLWinXfmPop (glwin); GLWinSwap (glwin); sleep(1); } sleep(2); /* use umbrella vectors, detail and shape */ vis_VisContextSetVectorType (vc,VIS_VECTORUMBRELLA); vis_TriadSetParami (triad,TRIAD_DETAIL,VIS_ON); vis_TriadSetParami (triad,TRIAD_SHAPE,VIS_ON); /* draw detailed triads */ for(i = 0; i < 8; i++) { GLWinClear (glwin); GLWinColor (glwin,ctex); GLWinText (glwin,xtex,"Detailed Triads"); GLWinXfmPush (glwin); GLWinRotate (glwin,i*8.,'x'); GLWinRotate (glwin,i*4.,'y'); x[0] = 0.; x[1] = 0.; x[2] = 0.; vis_TriadDraw (triad,SYS_CARTESIAN,x,tm); x[0] = 2.; x[1] = 0.; x[2] = 0.; vis_TriadDraw (triad,SYS_CYLINDRICAL,x,tm); x[0] = 4.; x[1] = 0.; x[2] = 0.; vis_TriadDraw (triad,SYS_CYLINDRICAL_ALT,x,tm); x[0] = 0.; x[1] = 2.; x[2] = 0.; vis_TriadDraw (triad,SYS_SPHERICAL,x,tm); x[0] = 2.; x[1] = 2.; x[2] = 0.; vis_TriadDraw (triad,SYS_SPHERICAL_ALT,x,tm); x[0] = 4.; x[1] = 2.; x[2] = 0.; vis_TriadDraw (triad,SYS_TOROIDAL,x,tm); GLWinXfmPop (glwin); GLWinSwap (glwin); sleep(1); } sleep(4); /* free all objects */ vgl_DrawFunEnd (df); vis_VisContextEnd (vc); vis_ColorMapEnd (cmap); vis_TriadEnd (triad); GLWinEnd (glwin); return 0; }
#include "base/base.h" #include "vgl/vgl.h" #include "vis/vis.h" #include "glwin.h" static Vfloat rgb[9][3] = { {.5,.5,.5}, {1.,0.,0.}, {0.,1.,0.}, {0.,0.,1.}, {0.,1.,1.}, {1.,0.,1.}, {1.,1.,0.}, {.2,.2,.2}, {1.,1.,1.} }; static Vfloat xtex[3] = { -1.8, 1.8, 0. }; static Vfloat ctex[3] = { 1., 1., 1. }; /*---------------------------------------------------------------------- Compute and Draw TEE Beam Section ----------------------------------------------------------------------*/ int main() { vgl_DrawFun *df; vis_VisContext *vc; vis_ColorMap *cmap; vis_Levels *levels; vis_BeamSect *beamsect; GLWin *glwin; Vfloat dimes[5]; Vfloat x[3], tm[3][3]; Vfloat props[BEAMSECT_MAXPROPS]; Vfloat dmat[21]; /* create GL device */ glwin = GLWinBegin (); GLWinCreateWindow (glwin,200,200,400,400); GLWinOrtho (glwin,-2.,2.,-2.,2.,-2.,2.); /* create draw function object for GL */ df = vgl_DrawFunBegin (); GLWinDrawFun (glwin,df); vc = vis_VisContextBegin (); vis_VisContextSetColor (vc,0); vis_VisContextSetXYZColor (vc,1,2,3); vis_VisContextSetABCColor (vc,8,7,6); vis_VisContextSetEdge (vc,VIS_ON); vis_VisContextSetFill (vc,VIS_ON); vis_VisContextSetSize (vc,.5); vis_VisContextSetMinorSize (vc,.2); vis_VisContextSetMapColor (vc,VIS_ON); /* levels for beam section */ levels = vis_LevelsBegin (); vis_LevelsDef (levels,LEVELS_LINEAR,7); /* color map */ cmap = vis_ColorMapBegin (); vis_ColorMapSetType (cmap,COLORMAP_TRUECOLOR); vis_ColorMapSetRGB (cmap,9,0,rgb); /* create beamsect object and set objects */ beamsect = vis_BeamSectBegin (); vis_BeamSectSetObject (beamsect,VGL_DRAWFUN,df); vis_BeamSectSetObject (beamsect,VIS_VISCONTEXT,vc); vis_BeamSectSetObject (beamsect,VIS_COLORMAP,cmap); vis_BeamSectSetObject (beamsect,VIS_LEVELS,levels); /* set display parameters */ vis_BeamSectSetParami (beamsect,BEAMSECT_AXESBASIC,VIS_ON); vis_BeamSectSetParami (beamsect,BEAMSECT_AXESPRINCIPAL,VIS_ON); vis_BeamSectSetParami (beamsect,BEAMSECT_CENTROID,BEAMSECT_CENTROID_CIRCLE); vis_BeamSectSetParami (beamsect,BEAMSECT_SHEARCENTER,VIS_ON); /* define TEE section */ vis_BeamSectDef (beamsect,BEAMSECT_TEE); dimes[0] = 3.; dimes[1] = 2.; dimes[2] = .1; dimes[3] = .3; dimes[4] = .2; vis_BeamSectSetDimensions (beamsect,dimes); /* compute and get section properties */ vis_BeamSectProps (beamsect); vis_BeamSectGetProps (beamsect,props,dmat); /* print section properties */ printf("\n"); printf("A = %f\n",props[0]); printf("Iyy = %f\n",props[1]); printf("Izz = %f\n",props[2]); printf("Iyz = %f\n",props[3]); printf("Ang = %f\n",props[4]); printf("J = %f\n",props[5]); printf("Asy = %f\n",props[6]); printf("Asz = %f\n",props[7]); printf("Ey = %f\n",props[9]); printf("Ez = %f\n",props[10]); printf("Dsy = %f\n",props[11]); printf("Dsz = %f\n",props[12]); printf("Cw = %f\n",props[13]); printf("Ny = %f\n",props[14]); printf("Nz = %f\n",props[15]); /* draw */ GLWinClear (glwin); GLWinColor (glwin,ctex); GLWinText (glwin,xtex,"TEE Beam Section"); /* set position */ x[0] = 0.; x[1] = 0.; x[2] = 0.; /* set orientation - x' out, y' right, z' up */ tm[0][0] = 0.; tm[0][1] = 0.; tm[0][2] = 1.; tm[1][0] = 1.; tm[1][1] = 0.; tm[1][2] = 0.; tm[2][0] = 0.; tm[2][1] = 1.; tm[2][2] = 0.; vis_BeamSectDraw (beamsect,x,tm,VIS_OFF); GLWinSwap (glwin); sleep(5); /* free all objects */ vgl_DrawFunEnd (df); vis_VisContextEnd (vc); vis_ColorMapEnd (cmap); vis_LevelsEnd (levels); vis_BeamSectEnd (beamsect); GLWinEnd (glwin); return 0; }
For illustration, the location of point 2 is repeatedly moved by increments of .01 along the positive x axis and the section is recalculated and drawn.
#include "base/base.h" #include "vgl/vgl.h" #include "vis/vis.h" #include "glwin.h" static Vfloat rgb[9][3] = { {.5,.5,.5}, {1.,0.,0.}, {0.,1.,0.}, {0.,0.,1.}, {0.,1.,1.}, {1.,0.,1.}, {1.,1.,0.}, {.2,.2,.2}, {1.,1.,1.} }; static Vfloat xtex[3] = { -1.8, 1.8, 0. }; static Vfloat ctex[3] = { 1., 1., 1. }; /*---------------------------------------------------------------------- Compute and Draw User Defined Beam Section ----------------------------------------------------------------------*/ int main() { vgl_DrawFun *df; vis_VisContext *vc; vis_ColorMap *cmap; vis_Levels *levels; vis_BeamSect *beamsect; GLWin *glwin; int i, n; Vfloat xp[6][2] = { {.2,.2}, {2.,.2}, {.2,1.5}, {.4,.4}, {1.,.4}, {.4,1.} }; Vint ix[2][3] = { {1, 2, 3}, {4, 5, 6} }; Vfloat x[3], tm[3][3]; Vfloat props[BEAMSECT_MAXPROPS]; Vfloat dmat[21]; /* create GL device */ glwin = GLWinBegin (); GLWinCreateWindow (glwin,200,200,400,400); GLWinOrtho (glwin,-2.,2.,-2.,2.,-2.,2.); /* create draw function object for GL */ df = vgl_DrawFunBegin (); GLWinDrawFun (glwin,df); vc = vis_VisContextBegin (); vis_VisContextSetColor (vc,0); vis_VisContextSetXYZColor (vc,1,2,3); vis_VisContextSetABCColor (vc,8,7,6); vis_VisContextSetEdge (vc,VIS_ON); vis_VisContextSetFill (vc,VIS_ON); vis_VisContextSetSize (vc,.5); vis_VisContextSetMinorSize (vc,.2); vis_VisContextSetMapColor (vc,VIS_ON); /* levels for beam section */ levels = vis_LevelsBegin (); vis_LevelsDef (levels,LEVELS_LINEAR,7); /* color map */ cmap = vis_ColorMapBegin (); vis_ColorMapSetType (cmap,COLORMAP_TRUECOLOR); vis_ColorMapSetRGB (cmap,9,0,rgb); /* create beamsect object and set objects */ beamsect = vis_BeamSectBegin (); vis_BeamSectSetObject (beamsect,VGL_DRAWFUN,df); vis_BeamSectSetObject (beamsect,VIS_VISCONTEXT,vc); vis_BeamSectSetObject (beamsect,VIS_COLORMAP,cmap); vis_BeamSectSetObject (beamsect,VIS_LEVELS,levels); /* set display parameters */ vis_BeamSectSetParami (beamsect,BEAMSECT_AXESBASIC,VIS_ON); vis_BeamSectSetParami (beamsect,BEAMSECT_AXESPRINCIPAL,VIS_ON); vis_BeamSectSetParami (beamsect,BEAMSECT_CENTROID,BEAMSECT_CENTROID_CIRCLE); vis_BeamSectSetParami (beamsect,BEAMSECT_SHEARCENTER,VIS_ON); /* define user defined section */ vis_BeamSectDef (beamsect,BEAMSECT_GEOMETRY); for(i = 1; i <= 6; i++) { vis_BeamSectSetPoint (beamsect,i,xp[i-1]); } vis_BeamSectSetLoop (beamsect,1,1,3,ix[0]); vis_BeamSectSetLoop (beamsect,2,0,3,ix[1]); /* loop, changing point 2 */ for(n = 0; n < 100; n++) { /* compute and get section properties */ vis_BeamSectProps (beamsect); vis_BeamSectGetProps (beamsect,props,dmat); /* print section properties */ printf("\n"); printf("A = %f\n",props[0]); printf("Iyy = %f\n",props[1]); printf("Izz = %f\n",props[2]); printf("Iyz = %f\n",props[3]); printf("Ang = %f\n",props[4]); printf("J = %f\n",props[5]); printf("Asy = %f\n",props[6]); printf("Asz = %f\n",props[7]); printf("Asyz= %f\n",props[8]); printf("Ey = %f\n",props[9]); printf("Ez = %f\n",props[10]); printf("Dsy = %f\n",props[11]); printf("Dsz = %f\n",props[12]); printf("Cw = %f\n",props[13]); /* draw */ GLWinClear (glwin); GLWinColor (glwin,ctex); GLWinText (glwin,xtex,"User Defined Beam Section"); /* set position */ x[0] = -1.; x[1] = -1.; x[2] = 0.; /* set orientation - x' out, y' right, z' up */ tm[0][0] = 0.; tm[0][1] = 0.; tm[0][2] = 1.; tm[1][0] = 1.; tm[1][1] = 0.; tm[1][2] = 0.; tm[2][0] = 0.; tm[2][1] = 1.; tm[2][2] = 0.; vis_BeamSectDraw (beamsect,x,tm,VIS_OFF); GLWinSwap (glwin); /* increment point 2 */ xp[1][0] += .01; vis_BeamSectSetPoint (beamsect,2,xp[1]); } sleep(5); /* free all objects */ vgl_DrawFunEnd (df); vis_VisContextEnd (vc); vis_ColorMapEnd (cmap); vis_LevelsEnd (levels); vis_BeamSectEnd (beamsect); GLWinEnd (glwin); return 0; }
The fifth sequence renders the beam using the so-called "polyline" representation of the beam section. The polyline representation of the general GEOMETRY section must be defined using vis_BeamSectSetPolyLine or else the polyline representation will not be drawn. The polyline representation is more economical than drawing the full surface of the beam section in detail. Note that color mapping should be explicitly disabled so that the individual polylines representing the beam section are not drawn in different colors.
#include "base/base.h" #include "vgl/vgl.h" #include "vis/vis.h" #include "glwin.h" static Vfloat rgb[9][3] = { {.5,.5,.5}, {1.,0.,0.}, {0.,1.,0.}, {0.,0.,1.}, {0.,1.,1.}, {1.,0.,1.}, {1.,1.,0.}, {.2,.2,.2}, {1.,1.,1.} }; static Vfloat xtex[3] = { -1.8, 1.8, 0. }; static Vfloat ctex[3] = { 1., 1., 1. }; /* beam element node point locations */ static Vfloat xbeam[3][3] = { {-1.5,.3,0.}, {0.,0.,0.}, {1.5,.3,0.} }; /* dimensions of TEE */ static Vfloat dimes[5] = { 3., 2., .1, .3, .2 }; /* general GEOMETRY */ static Vfloat xp[6][2] = { {.2,.2}, {2.,.2}, {.2,1.5}, {.4,.4}, {1.,.4}, {.4,1. } }; static Vint ix[2][3] = { {1, 2, 3}, {4, 5, 6} }; /* connected SEGMENTS */ static Vfloat xs[6][2] = { {.2,.2}, {.2,1.}, {.5,1.}, {.5,.2}, {.9,.2}, {.9,1.} }; static Vfloat ts[6] = { .05, .1, .05, .1, .05 }; /*---------------------------------------------------------------------- Draw TEE and GEOMETRY Beam Element ----------------------------------------------------------------------*/ int main() { vgl_DrawFun *df; vis_VisContext *vc; vis_ColorMap *cmap; vis_Levels *levels; vis_BeamSect *beamsect; vis_BeamElem *beamelem; GLWin *glwin; int i, j, k; Vfloat factors[2]; Vchar text[65]; /* create GL device */ glwin = GLWinBegin (); GLWinCreateWindow (glwin,200,200,400,400); GLWinOrtho (glwin,-2.,2.,-2.,2.,-3.,3.); /* create draw function object for GL */ df = vgl_DrawFunBegin (); GLWinDrawFun (glwin,df); vc = vis_VisContextBegin (); vis_VisContextSetColor (vc,0); vis_VisContextSetXYZColor (vc,1,2,3); vis_VisContextSetABCColor (vc,8,7,6); vis_VisContextSetEdge (vc,VIS_ON); vis_VisContextSetFill (vc,VIS_ON); vis_VisContextSetSize (vc,.5); vis_VisContextSetMinorSize (vc,.2); vis_VisContextSetMapColor (vc,VIS_ON); vis_VisContextSetRefinement (vc,2); vis_VisContextSetShade (vc,VIS_VERTEXSHADE); vis_VisContextSetMarkerType (vc,VIS_BOX); /* levels for beam section */ levels = vis_LevelsBegin (); vis_LevelsDef (levels,LEVELS_LINEAR,7); /* color map */ cmap = vis_ColorMapBegin (); vis_ColorMapSetType (cmap,COLORMAP_TRUECOLOR); vis_ColorMapSetRGB (cmap,9,0,rgb); /* create beamsect object and set objects */ beamsect = vis_BeamSectBegin (); vis_BeamSectSetObject (beamsect,VGL_DRAWFUN,df); vis_BeamSectSetObject (beamsect,VIS_VISCONTEXT,vc); vis_BeamSectSetObject (beamsect,VIS_COLORMAP,cmap); vis_BeamSectSetObject (beamsect,VIS_LEVELS,levels); /* set display parameters */ vis_BeamSectSetParami (beamsect,BEAMSECT_CENTROID,BEAMSECT_CENTROID_SPHERE); vis_BeamSectSetParami (beamsect,BEAMSECT_SHEARCENTER,VIS_ON); vis_BeamSectSetParami (beamsect,BEAMSECT_AXESBASIC,VIS_ON); vis_BeamSectSetParami (beamsect,BEAMSECT_AXESPRINCIPAL,VIS_ON); /* create beam element object and set objects */ beamelem = vis_BeamElemBegin (); vis_BeamElemSetObject (beamelem,VGL_DRAWFUN,df); vis_BeamElemSetObject (beamelem,VIS_VISCONTEXT,vc); vis_BeamElemSetObject (beamelem,VIS_COLORMAP,cmap); vis_BeamElemSetObject (beamelem,VIS_BEAMSECT,beamsect); vis_BeamElemSetParami (beamelem,BEAMELEM_SECT,VIS_ON); vis_BeamElemSetTopology (beamelem,VIS_SHAPELINE,3); factors[0] = 1.; factors[1] = .5; vis_BeamElemSetEndFactors (beamelem,factors); /* draw */ /* three beam types */ for(k = 0; k < 3; k++) { /* define TEE section */ if(k == 0) { strcpy(text,"TEE Beam Element"); vis_BeamSectDef (beamsect,BEAMSECT_TEE); vis_BeamSectSetDimensions (beamsect,dimes); /* define general GEOMETRY section */ } else if(k == 1) { strcpy(text,"GEOMETRY Beam Element"); vis_BeamSectDef (beamsect,BEAMSECT_GEOMETRY); for(i = 1; i <= 6; i++) { vis_BeamSectSetPoint (beamsect,i,xp[i-1]); } vis_BeamSectSetLoop (beamsect,1,1,3,ix[0]); vis_BeamSectSetLoop (beamsect,2,0,3,ix[1]); /* use outer loop as closed loop polyline */ vis_BeamSectSetPolyLine (beamsect,1,VIS_ON,3,ix[0]); /* define connected SEGMENTS section */ } else if(k == 2) { strcpy(text,"SEGMENTS Beam Element"); vis_BeamSectDef (beamsect,BEAMSECT_SEGMENTS); vis_BeamSectSetSegments (beamsect,5,ts,xs); } vis_VisContextSetMapColor (vc,VIS_ON); vis_BeamSectSetParami (beamsect,BEAMSECT_POLYLINE,VIS_OFF); /* 5 beam drawing styles */ for(j = 0; j < 5; j++) { if(j == 0) { vis_VisContextSetElemLoc (vc,VIS_ELEMLOC_CENTROID); vis_VisContextSetElemRep (vc,VIS_ELEMREP_SEMI); } else if(j == 1) { vis_VisContextSetElemLoc (vc,VIS_ELEMLOC_CORNERS); vis_VisContextSetElemRep (vc,VIS_ELEMREP_SEMI); } else if(j == 2) { vis_VisContextSetElemLoc (vc,VIS_ELEMLOC_NODES); vis_VisContextSetElemRep (vc,VIS_ELEMREP_SEMI); } else if(j == 3) { vis_VisContextSetElemRep (vc,VIS_ELEMREP_SOLID); } else if(j == 4) { vis_VisContextSetElemRep (vc,VIS_ELEMREP_SOLID); vis_VisContextSetMapColor (vc,VIS_OFF); vis_BeamSectSetParami (beamsect,BEAMSECT_POLYLINE,VIS_ON); } /* rotate 10 times */ for(i = 0; i < 10; i++) { GLWinClear (glwin); GLWinColor (glwin,ctex); GLWinText (glwin,xtex,text); GLWinXfmPush (glwin); GLWinRotate (glwin,i*4.,'x'); GLWinRotate (glwin,i*12.,'y'); vis_BeamElemCurv (beamelem,xbeam,VIS_NODATA,NULL,VIS_NODATA,NULL); GLWinXfmPop (glwin); GLWinSwap (glwin); sleep(1); } } } sleep(5); /* free all objects */ vgl_DrawFunEnd (df); vis_VisContextEnd (vc); vis_ColorMapEnd (cmap); vis_LevelsEnd (levels); vis_BeamSectEnd (beamsect); vis_BeamElemEnd (beamelem); GLWinEnd (glwin); return 0; }
#include "base/base.h" #include "vgl/vgl.h" #include "vis/vis.h" #include "glwin.h" static Vfloat rgb[9][3] = { {.5,.5,.5}, {1.,0.,0.}, {0.,1.,0.}, {0.,0.,1.}, {0.,1.,1.}, {1.,0.,1.}, {1.,1.,0.}, {.2,.2,.2}, {1.,1.,1.} }; static Vfloat xtex[3] = { -1.8, 1.8, 0. }; static Vfloat ctex[3] = { 1., 1., 1. }; /*---------------------------------------------------------------------- Compute and Plot Strain on a TEE Beam Section ----------------------------------------------------------------------*/ int main() { vgl_DrawFun *df; vis_VisContext *vc; vis_ColorMap *cmap; vis_Levels *levels; vis_BeamSect *beamsect; vis_Contour *contour; GLWin *glwin; Vint i, j; Vfloat dimes[5]; Vfloat x[3], tm[3][3]; Vfloat elas[2]; Vint npoints, nloops, nlines, ntris, nqualpnts, nqualtris; Vfloat eks[6], strs[6], strn[6]; Vfloat st[6], xt[6][3]; Vfloat *stptr, stmin, stmax; Vint ix[6], mid; Vfloat props[BEAMSECT_MAXPROPS], dmat[21]; Vdouble err; /* create GL device */ glwin = GLWinBegin (); GLWinCreateWindow (glwin,200,200,600,600); GLWinOrtho (glwin,-2.,2.,-2.,2.,-2.,2.); /* create draw function object for GL */ df = vgl_DrawFunBegin (); GLWinDrawFun (glwin,df); vc = vis_VisContextBegin (); vis_VisContextSetColor (vc,0); vis_VisContextSetXYZColor (vc,1,2,3); vis_VisContextSetABCColor (vc,8,7,6); vis_VisContextSetEdge (vc,VIS_ON); vis_VisContextSetFill (vc,VIS_OFF); vis_VisContextSetSize (vc,.5); vis_VisContextSetMinorSize (vc,.2); vis_VisContextSetMapColor (vc,VIS_ON); vis_VisContextSetIsoValType (vc,VIS_ISOVALTONE); /* levels for beam section */ levels = vis_LevelsBegin (); vis_LevelsDef (levels,LEVELS_LINEAR,7); /* color map */ cmap = vis_ColorMapBegin (); vis_ColorMapSetType (cmap,COLORMAP_TRUECOLOR); vis_ColorMapSetRGB (cmap,9,0,rgb); /* create contour object and set objects */ contour = vis_ContourBegin (); vis_ContourSetObject (contour,VGL_DRAWFUN,df); vis_ContourSetObject (contour,VIS_VISCONTEXT,vc); vis_ContourSetObject (contour,VIS_COLORMAP,cmap); vis_ContourSetObject (contour,VIS_LEVELS,levels); /* create beamsect object and set objects */ beamsect = vis_BeamSectBegin (); vis_BeamSectSetObject (beamsect,VGL_DRAWFUN,df); vis_BeamSectSetObject (beamsect,VIS_VISCONTEXT,vc); vis_BeamSectSetObject (beamsect,VIS_COLORMAP,cmap); vis_BeamSectSetObject (beamsect,VIS_LEVELS,levels); /* define TEE section */ vis_BeamSectDef (beamsect,BEAMSECT_TEE); dimes[0] = 3.; dimes[1] = 2.; dimes[2] = .1; dimes[3] = .3; dimes[4] = .2; vis_BeamSectSetDimensions (beamsect,dimes); /* set elastic properties */ elas[0] = 10000000.; elas[1] = .3; mid = 1; vis_BeamSectSetElasProp (beamsect,mid,SYS_MAT_ISOTROPIC,elas); /* option to draw quality grid edges */ vis_BeamSectSetParami (beamsect,BEAMSECT_QUALITYGRID,SYS_ON); /* option to enable adaptive error refinement, set to .5 percent */ vis_BeamSectSetParami (beamsect,BEAMSECT_REFINE,SYS_ON); vis_BeamSectSetParamd (beamsect,BEAMSECT_ERRORTOL,.005); /* compute section properties */ vis_BeamSectProps (beamsect); vis_BeamSectGetProps (beamsect,props,dmat); /* print section properties */ printf("\n"); printf("A = %f\n",props[0]); printf("Iyy = %f\n",props[1]); printf("Izz = %f\n",props[2]); printf("Iyz = %f\n",props[3]); printf("Ang = %f\n",props[4]); printf("J = %f\n",props[5]); printf("Asy = %f\n",props[6]); printf("Asz = %f\n",props[7]); printf("Asyz= %f\n",props[8]); printf("Ey = %f\n",props[9]); printf("Ez = %f\n",props[10]); printf("Dsy = %f\n",props[11]); printf("Dsz = %f\n",props[12]); printf("Cw = %f\n",props[13]); printf("Ny = %f\n",props[14]); printf("Nz = %f\n",props[15]); /* retrieve error */ vis_BeamSectGetDouble (beamsect,BEAMSECT_ERROR,&err); printf("error= %e\n",err); /* draw */ GLWinClear (glwin); GLWinColor (glwin,ctex); GLWinText (glwin,xtex,"TEE Beam Section"); /* set position */ x[0] = 0.; x[1] = 0.; x[2] = 0.; /* set orientation - x' out, y' right, z' up */ tm[0][0] = 0.; tm[0][1] = 0.; tm[0][2] = 1.; tm[1][0] = 1.; tm[1][1] = 0.; tm[1][2] = 0.; tm[2][0] = 0.; tm[2][1] = 1.; tm[2][2] = 0.; /* set centroidal strain, curvature, twist */ eks[0] = .001; eks[1] = .002; eks[2] = .003; eks[3] = .004; eks[4] = .005; eks[5] = .006; /* determine number of quality points and triangles */ vis_BeamSectGetNum (beamsect,&npoints,&nloops,&nlines,&ntris, &nqualpnts,&nqualtris); /* allocate memory */ stptr = (Vfloat*) malloc(sizeof(Vfloat)*nqualpnts); /* evaluate stress and strain at each quality point */ for(i = 1; i <= nqualpnts; i++) { vis_BeamSectStrsStrn (beamsect,i,eks,strs,strn); /* plot ezx strain */ stptr[i-1] = strn[5]; if(i == 1) { stmin = stptr[i-1]; stmax = stptr[i-1]; } else { if(stptr[i-1] < stmin) stmin = stptr[i-1]; if(stptr[i-1] > stmax) stmax = stptr[i-1]; } } /* set minimum and maximum in Levels for contouring */ vis_LevelsSetMinMax (levels,stmin,stmax); vis_LevelsGenerate (levels,LEVELS_PADNONE); vis_ContourSetTopology (contour,VIS_SHAPETRI,3,0); /* loop through triangles */ for(i = 1; i <= nqualtris; i++) { vis_BeamSectGetQualTri (beamsect,i,ix,&mid); for(j = 0; j < 6; j++) { vis_BeamSectGetPoint (beamsect,ix[j],xt[j]); xt[j][2] = 0.; st[j] = stptr[ix[j]-1]; } vis_ContourCurv (contour,st,xt,VIS_NODATA,NULL); } vis_BeamSectDraw (beamsect,x,tm,VIS_OFF); GLWinSwap (glwin); sleep(10); /* free memory */ free(stptr); /* free all objects */ vgl_DrawFunEnd (df); vis_VisContextEnd (vc); vis_ColorMapEnd (cmap); vis_LevelsEnd (levels); vis_BeamSectEnd (beamsect); vis_ContourEnd (contour); GLWinEnd (glwin); return 0; }
The axial stress is first contoured over the complete surface of the beam by processing all the loops which define the beam section. Beam element endpoint coordinates are computed and stress is gathered into two data arrays which are then contoured using vis_ContourCurv for each loop. Care is taken to ensure that the normal to the surface is outward. Stress is contoured on the endpoint sections by looping through the section triangulation and contouring each triangle individually. It may be desirable to enable back face culling in the underlying graphics system when rendering beam elements contoured in this manner.
The axial stress is then contoured on the "polyline" representation of the beam element by looping through the individual polylines and contouring each in a manner similar to processing loops above.
#include "base/base.h" #include "vgl/vgl.h" #include "vis/vis.h" #include "glwin.h" static Vfloat rgb[9][3] = { {.5,.5,.5}, {1.,0.,0.}, {0.,1.,0.}, {0.,0.,1.}, {0.,1.,1.}, {1.,0.,1.}, {1.,1.,0.}, {.2,.2,.2}, {1.,1.,1.} }; static Vfloat xtex[3] = { -1.8, 1.8, 0. }; static Vfloat ctex[3] = { 1., 1., 1. }; static Vfloat xbeam[2][3] = { {0.,0.,0.}, {1.5,.3,0.} }; /*---------------------------------------------------------------------- Contour Stress on a TEE Beam Element ----------------------------------------------------------------------*/ int main() { vgl_DrawFun *df; vis_VisContext *vc; vis_ColorMap *cmap; vis_Levels *levels; vis_BeamSect *beamsect; vis_BeamElem *beamelem; vis_Contour *contour; GLWin *glwin; int i, j, n, nn; Vfloat dimes[5]; Vint npoints, nloops, nlines, ntris, nqualpnts, nqualtris; Vfloat xs[2], xb[2][3]; Vint type, npts, *ix; Vint reflectflag; Vfloat (*xl)[3], *sl, *s1, *s2; Vfloat props[BEAMSECT_MAXPROPS]; Vfloat dmat[21]; Vfloat area, iyy, izz; Vfloat nx1, my1, mz1; Vfloat nx2, my2, mz2; Vfloat smin, smax; Vfloat st1[3], xt1[3][3]; Vfloat st2[3], xt2[3][3]; /* create GL device */ glwin = GLWinBegin (); GLWinCreateWindow (glwin,200,200,400,400); GLWinOrtho (glwin,-2.,2.,-2.,2.,-2.,2.); /* create draw function object for GL */ df = vgl_DrawFunBegin (); GLWinDrawFun (glwin,df); vc = vis_VisContextBegin (); vis_VisContextSetShade (vc,VIS_VERTEXSHADE); vis_VisContextSetIsoValType (vc,VIS_ISOVALFRINGE); /* levels for contouring */ levels = vis_LevelsBegin (); vis_LevelsDef (levels,LEVELS_LINEAR,7); /* color map */ cmap = vis_ColorMapBegin (); vis_ColorMapSetType (cmap,COLORMAP_TRUECOLOR); vis_ColorMapSetRGB (cmap,9,0,rgb); /* create contour object and set objects */ contour = vis_ContourBegin (); vis_ContourSetObject (contour,VGL_DRAWFUN,df); vis_ContourSetObject (contour,VIS_VISCONTEXT,vc); vis_ContourSetObject (contour,VIS_COLORMAP,cmap); vis_ContourSetObject (contour,VIS_LEVELS,levels); /* create beamsect object */ beamsect = vis_BeamSectBegin (); /* define TEE section */ vis_BeamSectDef (beamsect,BEAMSECT_TEE); dimes[0] = 3.; dimes[1] = 2.; dimes[2] = .1; dimes[3] = .3; dimes[4] = .2; vis_BeamSectSetDimensions (beamsect,dimes); /* compute and retrieve section properties */ vis_BeamSectProps (beamsect); vis_BeamSectGetProps (beamsect,props,dmat); area = props[0]; iyy = props[1]; izz = props[2]; /* create beam element object and set objects */ beamelem = vis_BeamElemBegin (); vis_BeamElemSetObject (beamelem,VIS_BEAMSECT,beamsect); /* straight beam segment */ vis_BeamElemSetTopology (beamelem,VIS_SHAPELINE,2); /* get number of points and loops */ vis_BeamSectGetNum (beamsect,&npoints,&nloops,&nlines,&ntris, &nqualpnts,&nqualtris); /* allocate memory for possibly all point ids */ ix = (Vint*)malloc(sizeof(Vint)*npoints); /* allocate memory for point stress data at each end */ s1 = (Vfloat*)malloc(sizeof(Vfloat)*npoints); s2 = (Vfloat*)malloc(sizeof(Vfloat)*npoints); /* assume some end forces and moments */ nx1 = 100.; my1 = 3.; mz1 = 20.; nx2 = 100.; my2 = 6.; mz2 = 40.; /* compute stresses */ smin = smax = 0.; for(n = 1; n <= npoints; n++) { vis_BeamSectGetPoint (beamsect,n,xs); /* first end */ s1[n-1] = nx1/area + my1*xs[0]/iyy + mz1*xs[1]/izz; if(s1[n-1] < smin) smin = s1[n-1]; if(s1[n-1] > smax) smax = s1[n-1]; /* second end */ s2[n-1] = nx2/area + my2*xs[0]/iyy + mz2*xs[1]/izz; if(s2[n-1] < smin) smin = s2[n-1]; if(s2[n-1] > smax) smax = s2[n-1]; } /* generate contour levels */ vis_LevelsSetMinMax (levels,smin,smax); vis_LevelsGenerate (levels,LEVELS_PADNONE); /* allocate memory for local stress and coordinate arrays */ sl = (Vfloat*)malloc(sizeof(Vfloat)*2*(npoints+1)); xl = (Vfloat(*)[3])malloc(3*sizeof(Vfloat)*2*(npoints+1)); /* rotate display 30 times */ /* contour the complete surface of the beam */ for(i = 0; i < 30; i++) { GLWinClear (glwin); GLWinColor (glwin,ctex); GLWinText (glwin,xtex,"TEE Beam Complete Loop Surface Contour"); GLWinXfmPush (glwin); GLWinRotate (glwin,i*4.,'x'); GLWinRotate (glwin,i*12.,'y'); GLWinRotate (glwin,i*6.,'z'); /* loop over loops, the first loop is the outer loop */ for(j = 1; j <= nloops; j++) { vis_BeamSectGetLoop (beamsect,j,&type,&npts,ix); vis_ContourSetTopology (contour,VIS_SHAPEQUAD,2,npts+1); reflectflag = (j == 1); for(n = 0; n <= npts; n++) { nn = n%npts; /* compute coordinates */ vis_BeamElemCoords (beamelem,ix[nn],reflectflag,xbeam, VIS_NODATA,NULL,VIS_NODATA,NULL,&xl[2*n]); /* gather stress */ if(reflectflag) { sl[2*n+1] = s1[ix[nn]-1]; sl[2*n] = s2[ix[nn]-1]; } else { sl[2*n] = s1[ix[nn]-1]; sl[2*n+1] = s2[ix[nn]-1]; } } vis_ContourCurv (contour,sl,xl,VIS_NODATA,NULL); } /* cap ends, loop over tris */ vis_ContourSetTopology (contour,VIS_SHAPETRI,2,0); for(j = 1; j <= ntris; j++) { vis_BeamSectGetTri (beamsect,j,ix); for(n = 0; n < 3; n++) { vis_BeamElemCoords (beamelem,ix[n],0,xbeam, VIS_NODATA,NULL,VIS_NODATA,NULL,xb); /* invert first end to point outward */ xt1[2-n][0] = xb[0][0]; xt1[2-n][1] = xb[0][1]; xt1[2-n][2] = xb[0][2]; st1[2-n] = s1[ix[n]-1]; /* second end is already pointed outward */ xt2[n][0] = xb[1][0]; xt2[n][1] = xb[1][1]; xt2[n][2] = xb[1][2]; st2[n] = s2[ix[n]-1]; } vis_ContourCurv (contour,st1,xt1,VIS_NODATA,NULL); vis_ContourCurv (contour,st2,xt2,VIS_NODATA,NULL); } GLWinXfmPop (glwin); GLWinSwap (glwin); sleep(1); } sleep(5); /* rotate display 30 times */ /* contour the polyline representation of the beam */ for(i = 0; i < 30; i++) { GLWinClear (glwin); GLWinColor (glwin,ctex); GLWinText (glwin,xtex,"TEE Beam PolyLine Surface Contour"); GLWinXfmPush (glwin); GLWinRotate (glwin,i*4.,'x'); GLWinRotate (glwin,i*12.,'y'); GLWinRotate (glwin,i*6.,'z'); /* loop over polylines */ for(j = 1; j <= nlines; j++) { vis_BeamSectGetPolyLine (beamsect,j,&type,&npts,ix); for(n = 0; n < npts; n++) { /* compute coordinates */ vis_BeamElemCoords (beamelem,ix[n],0,xbeam, VIS_NODATA,NULL,VIS_NODATA,NULL,&xl[2*n]); /* gather stress */ sl[2*n] = s1[ix[n]-1]; sl[2*n+1] = s2[ix[n]-1]; } /* close polyline if necessary */ if(type == VIS_ON) { vis_ContourSetTopology (contour,VIS_SHAPEQUAD,2,npts+1); vis_BeamElemCoords (beamelem,ix[0],0,xbeam, VIS_NODATA,NULL,VIS_NODATA,NULL,&xl[2*npts]); sl[2*npts] = s1[ix[0]-1]; sl[2*npts+1] = s2[ix[0]-1]; } else { vis_ContourSetTopology (contour,VIS_SHAPEQUAD,2,npts); } vis_ContourCurv (contour,sl,xl,VIS_NODATA,NULL); } GLWinXfmPop (glwin); GLWinSwap (glwin); sleep(1); } sleep(5); /* free allocated memory */ free(ix); free(s1); free(s2); free(sl); free(xl); /* free all objects */ vgl_DrawFunEnd (df); vis_VisContextEnd (vc); vis_ColorMapEnd (cmap); vis_LevelsEnd (levels); vis_BeamSectEnd (beamsect); vis_BeamElemEnd (beamelem); vis_ContourEnd (contour); GLWinEnd (glwin); return 0; }
#include "base/base.h" #include "vgl/vgl.h" #include "vis/vis.h" #include "glwin.h" static Vfloat rgb[9][3] = { {.5,.5,.5}, {1.,0.,0.}, {0.,1.,0.}, {0.,0.,1.}, {0.,1.,1.}, {1.,0.,1.}, {1.,1.,0.}, {.2,.2,.2}, {1.,1.,1.} }; static Vfloat xtex[3] = { -1.8, 1.8, 0. }; static Vfloat ctex[3] = { 1., 1., 1. }; static Vfloat xbeam[3][3] = { {-1.5,.3,0.}, {0.,0.,0.}, {1.5,.3,0.} }; static Vfloat sbeam[3] = { 5., 3., 8. }; /*---------------------------------------------------------------------- Draw TEE Beam Element Bending Moment Diagram ----------------------------------------------------------------------*/ int main() { vgl_DrawFun *df; vis_VisContext *vc; vis_ColorMap *cmap; vis_Levels *levels; vis_BeamSect *beamsect; vis_BeamElem *beamelem; GLWin *glwin; int i, j; Vfloat dimes[5]; Vfloat factors[2]; /* create GL device */ glwin = GLWinBegin (); GLWinCreateWindow (glwin,200,200,400,400); GLWinOrtho (glwin,-2.,2.,-2.,2.,-2.,2.); /* create draw function object for GL */ df = vgl_DrawFunBegin (); GLWinDrawFun (glwin,df); vc = vis_VisContextBegin (); vis_VisContextSetColor (vc,0); vis_VisContextSetMinorColor (vc,8); vis_VisContextSetXYZColor (vc,1,2,3); vis_VisContextSetABCColor (vc,8,7,6); vis_VisContextSetEdge (vc,VIS_ON); vis_VisContextSetFill (vc,VIS_ON); vis_VisContextSetSize (vc,1.); vis_VisContextSetMinorSize (vc,.2); vis_VisContextSetMapColor (vc,VIS_ON); vis_VisContextSetMapSize (vc,VIS_ON); vis_VisContextSetRefinement (vc,2); vis_VisContextSetShade (vc,VIS_VERTEXSHADE); vis_VisContextSetMarkerType (vc,VIS_BOX); vis_VisContextSetIsoValType (vc,VIS_ISOVALFRINGE); /* levels for beam section */ levels = vis_LevelsBegin (); vis_LevelsDef (levels,LEVELS_LINEAR,7); vis_LevelsSetMinMax (levels,2.,8.); vis_LevelsGenerate (levels,LEVELS_PADNONE); /* color map */ cmap = vis_ColorMapBegin (); vis_ColorMapSetType (cmap,COLORMAP_TRUECOLOR); vis_ColorMapSetRGB (cmap,9,0,rgb); /* create beamsect object and set objects */ beamsect = vis_BeamSectBegin (); vis_BeamSectSetObject (beamsect,VGL_DRAWFUN,df); vis_BeamSectSetObject (beamsect,VIS_VISCONTEXT,vc); vis_BeamSectSetObject (beamsect,VIS_COLORMAP,cmap); vis_BeamSectSetObject (beamsect,VIS_LEVELS,levels); /* set display parameters */ vis_BeamSectSetParami (beamsect,BEAMSECT_CENTROID,BEAMSECT_CENTROID_SPHERE); vis_BeamSectSetParami (beamsect,BEAMSECT_SHEARCENTER,VIS_ON); vis_BeamSectSetParami (beamsect,BEAMSECT_AXESBASIC,VIS_ON); vis_BeamSectSetParami (beamsect,BEAMSECT_AXESPRINCIPAL,VIS_ON); /* define TEE section */ vis_BeamSectDef (beamsect,BEAMSECT_TEE); dimes[0] = 3.; dimes[1] = 2.; dimes[2] = .1; dimes[3] = .3; dimes[4] = .2; vis_BeamSectSetDimensions (beamsect,dimes); /* create beam element object and set objects */ beamelem = vis_BeamElemBegin (); vis_BeamElemSetObject (beamelem,VGL_DRAWFUN,df); vis_BeamElemSetObject (beamelem,VIS_VISCONTEXT,vc); vis_BeamElemSetObject (beamelem,VIS_COLORMAP,cmap); vis_BeamElemSetObject (beamelem,VIS_BEAMSECT,beamsect); vis_BeamElemSetObject (beamelem,VIS_LEVELS,levels); vis_BeamElemSetParami (beamelem,BEAMELEM_SECT,VIS_ON); vis_BeamElemSetTopology (beamelem,VIS_SHAPELINE,3); factors[0] = 1.; factors[1] = .5; vis_BeamElemSetEndFactors (beamelem,factors); /* draw */ for(j = 0; j < 5; j++) { if(j == 0) { vis_VisContextSetElemLoc (vc,VIS_ELEMLOC_CENTROID); vis_VisContextSetElemRep (vc,VIS_ELEMREP_SEMI); } else if(j == 1) { vis_VisContextSetElemLoc (vc,VIS_ELEMLOC_CORNERS); vis_VisContextSetElemRep (vc,VIS_ELEMREP_SEMI); } else if(j == 2) { vis_VisContextSetElemLoc (vc,VIS_ELEMLOC_NODES); vis_VisContextSetElemRep (vc,VIS_ELEMREP_SEMI); } else if(j == 3) { vis_VisContextSetElemRep (vc,VIS_ELEMREP_SOLID); } else if(j == 4) { vis_VisContextSetElemRep (vc,VIS_ELEMREP_SOLID); vis_VisContextSetMapColor (vc,VIS_OFF); vis_BeamSectSetParami (beamsect,BEAMSECT_POLYLINE,VIS_ON); } for(i = 0; i < 10; i++) { GLWinClear (glwin); GLWinColor (glwin,ctex); GLWinText (glwin,xtex,"TEE Beam Element"); GLWinXfmPush (glwin); GLWinRotate (glwin,i*4.,'x'); GLWinRotate (glwin,i*12.,'y'); /* draw diagram along y' axis */ vis_BeamElemDiagram (beamelem,sbeam,SYS_YAXIS, xbeam,VIS_NODATA,NULL,VIS_NODATA,NULL); /* draw beam */ vis_BeamElemCurv (beamelem,xbeam,VIS_NODATA,NULL,VIS_NODATA,NULL); GLWinXfmPop (glwin); GLWinSwap (glwin); sleep(1); } } sleep(5); /* free all objects */ vgl_DrawFunEnd (df); vis_VisContextEnd (vc); vis_ColorMapEnd (cmap); vis_LevelsEnd (levels); vis_BeamSectEnd (beamsect); vis_BeamElemEnd (beamelem); GLWinEnd (glwin); return 0; }
Because of the discontinuity in material properties, stress and strain recovery is done on an element-by-element basis. The results are printed and saved to a SDRC Universal file for further visualization.
#include <stdio.h> #include "vis/vis.h" static Vdouble vy[3] = {0.,1.,0.}; static Vdouble vz[3] = {0.,0.,1.}; static Vdouble origin[3] = {0.,0.,0.}; static Vint loop[3][4] = { {1,2,5,8},{2,3,4,5},{5,6,7,8} }; static Vdouble elast[3][2] = { {1.e+7,0.1},{2.e+6,0.2},{3.e+7,0.3} }; static Vdouble x[8][3] = { {0.,0.,0.}, {1.,0.,0.}, {5.,0.,0.}, {5.,2.,0.}, {1.,2.,0.}, {1.,4.,0.}, {0.,4.,0.}, {0.,2.,0.} }; /*---------------------------------------------------------------------- Compute Composite Beam Section Properties ----------------------------------------------------------------------*/ int main() { vis_BeamSect *beamsect; vis_Connect *connect; vis_State *states, *statee; vis_RProp *rprops, *rprope; vis_GridFun *gridfun; Vdouble eks[6], strs[36], strn[36]; Vint i, j, n; Vdouble props[BEAMSECT_MAXPROPS], dmat[21], xp[3]; Vint ix[6], mid; Vint npoints, nloops, nlines, ntris, nqualpnts, nqualtris; /* instance BeamSect for comparison */ beamsect = vis_BeamSectBegin (); /* generate data in arbitrary coordinates */ vis_BeamSectDef (beamsect,BEAMSECT_GEOMETRY); for(n = 1; n <= 8; n++) { vis_BeamSectSetPointdv (beamsect,n,x[n-1]); } for(n = 1; n <= 3; n++) { mid = n; vis_BeamSectSetLoop (beamsect,n,mid,4,loop[n-1]); vis_BeamSectSetElasPropdv (beamsect,mid,SYS_MAT_ISOTROPIC,elast[n-1]); } vis_BeamSectSetParami (beamsect,BEAMSECT_VABS,SYS_ON); vis_BeamSectProps (beamsect); vis_BeamSectGetPropsdv (beamsect,props,dmat); /* print Timoshenko stiffness matrix */ for(n = 0, i = 0; i < 6; i++) { for(j = 0; j <= i; j++, n++) { printf("%11.4e ",dmat[n]); } printf("\n"); } /* determine number of quality points and triangles */ vis_BeamSectGetNum (beamsect,&npoints,&nloops,&nlines,&ntris, &nqualpnts,&nqualtris); /* save model to IDEAS Universal file */ connect = vis_ConnectBegin (); vis_ConnectDef (connect,nqualpnts,nqualtris); for(n = 1; n <= nqualpnts; n++) { vis_BeamSectCoordsdv (beamsect,n,origin,vy,vz,xp); vis_ConnectSetCoordsdv (connect,n,xp); } for(n = 1; n <= nqualtris; n++) { vis_BeamSectGetQualTri (beamsect,n,ix,&mid); vis_ConnectSetTopology (connect,n,SYS_SHAPETRI,3,0,0); vis_ConnectSetElemNode (connect,n,ix); vis_ConnectSetElemAssoc (connect,VIS_MATLID,n,mid); } vis_ConnectWrite (connect,SYS_SDRC_UNIVERSAL,"exam13f.unv"); /* set stress and strain states */ gridfun = vis_GridFunBegin (); vis_ConnectGridFun (connect,gridfun); statee = vis_StateBegin (); vis_StateSetObject (statee,VIS_GRIDFUN,(Vobject*)gridfun); vis_StateDef (statee,nqualtris,SYS_ELEM,SYS_NODE,SYS_TENSOR); rprope = vis_RPropBegin (); vis_RPropSetType (rprope,SYS_RES_E); vis_RPropSetIds (rprope,1,0,0); states = vis_StateBegin (); vis_StateSetObject (states,VIS_GRIDFUN,(Vobject*)gridfun); vis_StateDef (states,nqualtris,SYS_ELEM,SYS_NODE,SYS_TENSOR); rprops = vis_RPropBegin (); vis_RPropSetType (rprops,SYS_RES_S); vis_RPropSetIds (rprops,1,0,0); /* set centroidal strain, curvature, twist */ eks[0] = .001; eks[1] = .002; eks[2] = .003; eks[3] = .004; eks[4] = .005; eks[5] = .006; /* evaluate stress and strain at each quality element */ for(n = 1; n <= nqualtris; n++) { vis_BeamSectGetQualTri (beamsect,n,ix,&mid); vis_BeamSectElemStrsStrndv (beamsect,n,eks,strs,strn); printf("element= %d, mid= %d\n",n,mid); for(i = 0; i < 6; ++i) { printf(" node= %d\n",i+1); printf(" strain= %11.4e %11.4e %11.4e %11.4e %11.4e %11.4e\n", strn[6*i ],strn[6*i+1],strn[6*i+2],strn[6*i+3],strn[6*i+4], strn[6*i+5]); printf(" stress= %11.4e %11.4e %11.4e %11.4e %11.4e %11.4e\n", strs[6*i ],strs[6*i+1],strs[6*i+2],strs[6*i+3],strs[6*i+4], strs[6*i+5]); vis_StateSetDatadv (statee,n,strn); vis_StateSetDatadv (states,n,strs); } } vis_StateWrite (statee,rprope,SYS_SDRC_UNIVERSAL,"exam13f.unv"); vis_StateWrite (states,rprops,SYS_SDRC_UNIVERSAL,"exam13f.unv"); /* clean up*/ vis_StateEnd (statee); vis_StateEnd (states); vis_RPropEnd (rprope); vis_RPropEnd (rprops); vis_GridFunEnd (gridfun); vis_ConnectEnd (connect); vis_BeamSectEnd (beamsect); return 0; }
#include "base/base.h" #include "vgl/vgl.h" #include "vis/vis.h" #include "glwin.h" static Vfloat rgb[9][3] = { {.5,.5,.5}, {1.,0.,0.}, {0.,1.,0.}, {0.,0.,1.}, {0.,1.,1.}, {1.,0.,1.}, {1.,1.,0.}, {.2,.2,.2}, {1.,1.,1.} }; static Vfloat xtex[3] = { -1.8, 1.8, 0. }; static Vfloat ctex[3] = { 1., 1., 1. }; /* beam element node point locations */ static Vfloat xbeam[2][3] = { {-1.0,.3,0.}, {1.0,.3,0.} }; /* dimensions of TEE */ static Vfloat dimes[5] = { 3., 2., .1, .3, .2 }; /* dimensions of geometry */ static Vfloat xp[6][2] = { {0.2,0.2}, {0.4,0.2}, {0.6,0.2}, {0.6,0.4}, {0.4,0.4}, {0.2,0.4} }; static Vint ix[6] = {1, 2, 3, 4, 5, 6}; /* 3 orientations of beam element axis */ static Vfloat mbeam[3][2][3] = { {{-1.0,.3,0.}, {1.0,.3,0}}, {{ 0.3,1.,0.}, {0.3,-1.,0}}, {{ 1.0,.3,1.}, {1.0,.3,-1.}} }; /*---------------------------------------------------------------------- Draw TEE Beam Element with Local Axis Orientations ----------------------------------------------------------------------*/ int main() { vgl_DrawFun *df; vis_VisContext *vc; vis_ColorMap *cmap; vis_Levels *levels; vis_BeamSect *beamsect; vis_BeamElem *beamelem; GLWin *glwin; int i, k; Vfloat vec[3]; Vfloat v1[2][3], v2[2][3]; Vchar text[65]; /* create GL device */ glwin = GLWinBegin (); GLWinCreateWindow (glwin,200,200,400,400); GLWinOrtho (glwin,-2.,2.,-2.,2.,-3.,3.); /* create draw function object for GL */ df = vgl_DrawFunBegin (); GLWinDrawFun (glwin,df); vc = vis_VisContextBegin (); vis_VisContextSetColor (vc,0); vis_VisContextSetXYZColor (vc,1,2,3); vis_VisContextSetABCColor (vc,8,7,6); vis_VisContextSetEdge (vc,VIS_ON); vis_VisContextSetFill (vc,VIS_ON); vis_VisContextSetSize (vc,.6); vis_VisContextSetMapColor (vc,VIS_ON); vis_VisContextSetRefinement (vc,2); vis_VisContextSetShade (vc,VIS_VERTEXSHADE); vis_VisContextSetMarkerType (vc,VIS_BOX); vis_VisContextSetElemRep (vc,VIS_ELEMREP_SOLID); vis_VisContextSetLineWidth (vc,2); /* levels for beam section */ levels = vis_LevelsBegin (); vis_LevelsDef (levels,LEVELS_LINEAR,7); /* color map */ cmap = vis_ColorMapBegin (); vis_ColorMapSetType (cmap,COLORMAP_TRUECOLOR); vis_ColorMapSetRGB (cmap,9,0,rgb); /* create beamsect object and set objects */ beamsect = vis_BeamSectBegin (); vis_BeamSectSetObject (beamsect,VGL_DRAWFUN,df); vis_BeamSectSetObject (beamsect,VIS_VISCONTEXT,vc); vis_BeamSectSetObject (beamsect,VIS_COLORMAP,cmap); vis_BeamSectSetObject (beamsect,VIS_LEVELS,levels); /* set display parameters */ vis_BeamSectSetParami (beamsect,BEAMSECT_AXESBASIC,VIS_ON); /* create beam element object and set objects */ beamelem = vis_BeamElemBegin (); vis_BeamElemSetObject (beamelem,VGL_DRAWFUN,df); vis_BeamElemSetObject (beamelem,VIS_VISCONTEXT,vc); vis_BeamElemSetObject (beamelem,VIS_COLORMAP,cmap); vis_BeamElemSetObject (beamelem,VIS_BEAMSECT,beamsect); vis_BeamElemSetParami (beamelem,BEAMELEM_SECT,VIS_ON); vis_BeamElemSetTopology (beamelem,VIS_SHAPELINE,2); vis_BeamSectDef (beamsect,BEAMSECT_TEE); vis_BeamSectSetDimensions (beamsect,dimes); /* orient beam element local y' axis */ for(k = 0; k < 3; k++) { /* orient along global z axis */ if(k == 0) { vec[0] = 0.; vec[1] = 0.; vec[2] = 1.; vis_BeamElemSetLocalSystem (beamelem,SYS_ELEMSYS_VECTOR,vec,0.); strcpy(text,"Global Z Axis"); /* orient 30. degrees from global z axis */ } else if(k == 1) { vec[0] = 0.; vec[1] = 0.; vec[2] = 1.; vis_BeamElemSetLocalSystem (beamelem,SYS_ELEMSYS_VECTOR,vec,30.); strcpy(text,"30. Degrees from Global Z Axis"); /* orient along global y axis */ } else if(k == 2) { vec[0] = 0.; vec[1] = 1.; vec[2] = 0.; vis_BeamElemSetLocalSystem (beamelem,SYS_ELEMSYS_VECTOR,vec,0.); strcpy(text,"Global Y Axis"); } /* rotate 10 times */ for(i = 0; i < 10; i++) { GLWinClear (glwin); GLWinColor (glwin,ctex); GLWinText (glwin,xtex,text); GLWinXfmPush (glwin); GLWinRotate (glwin,i*4.,'x'); GLWinRotate (glwin,i*12.,'y'); vis_BeamElemCurv (beamelem,xbeam,VIS_NODATA,NULL,VIS_NODATA,NULL); GLWinXfmPop (glwin); GLWinSwap (glwin); sleep(1); } } /* orient beam element local y' and z' axes */ for(k = 0; k < 2; k++) { /* rotate 15 times */ for(i = 0; i < 15; i++) { GLWinClear (glwin); GLWinColor (glwin,ctex); GLWinXfmPush (glwin); if(k == 0) { v1[0][0] = 0.; v1[0][1] = 1.; v1[0][2] = 0.; v1[1][0] = 0.; v1[1][1] = 1.; v1[1][2] = 1.; strcpy(text,"Twisted Beam"); } else if(k == 1) { v1[0][0] = 0.; v1[0][1] = 1.; v1[0][2] = 0.; v1[1][0] = 0.; v1[1][1] = 1.; v1[1][2] = 0.; v2[0][0] = -1.; v2[0][1] = 0.; v2[0][2] = 1.; v2[1][0] = +1.; v2[1][1] = 0.; v2[1][2] = 1.; strcpy(text,"Tilted Beam"); } GLWinText (glwin,xtex,text); GLWinRotate (glwin,i*4.,'x'); GLWinRotate (glwin,i*12.,'y'); /* twisted beam */ if(k == 0) { vis_BeamElemCurv (beamelem,xbeam, VIS_VERTEXDATA,v1,VIS_NODATA,NULL); /* tilted beam*/ } else if(k == 1) { vis_BeamElemCurv (beamelem,xbeam, VIS_VERTEXDATA,v1,VIS_VERTEXDATA,v2); } GLWinXfmPop (glwin); GLWinSwap (glwin); sleep(1); } } /* user defined geometry */ vis_BeamSectDef (beamsect,BEAMSECT_GEOMETRY); for(i = 1; i <= 6; i++) { vis_BeamSectSetPoint (beamsect,i,xp[i-1]); } vis_BeamSectSetLoop (beamsect,1,1,6,ix); /* orient beam element x' axis along global x, y and z */ for(k = 0; k < 3; k++) { /* local x' along global x, local y' along global z */ if(k == 0) { vec[0] = 0.; vec[1] = 0.; vec[2] = 1.; vis_BeamElemSetLocalSystem (beamelem,SYS_ELEMSYS_VECTOR,vec,0.); strcpy(text,"X' along Global X, Y' along Global Z"); /* local x' along global y, local y' along global x */ } else if(k == 1) { vec[0] = 1.; vec[1] = 0.; vec[2] = 0.; vis_BeamElemSetLocalSystem (beamelem,SYS_ELEMSYS_VECTOR,vec,0.); strcpy(text,"X' along Global Y, Y' along Global X"); /* local x' along global z, local y' along global y */ } else if(k == 2) { vec[0] = 0.; vec[1] = 1.; vec[2] = 0.; vis_BeamElemSetLocalSystem (beamelem,SYS_ELEMSYS_VECTOR,vec,0.); strcpy(text,"X' along Global Z, Y' along Global Y"); } /* rotate 10 times */ for(i = 0; i < 10; i++) { GLWinClear (glwin); GLWinColor (glwin,ctex); GLWinText (glwin,xtex,text); GLWinXfmPush (glwin); GLWinRotate (glwin,i*4.,'x'); GLWinRotate (glwin,i*12.,'y'); vis_BeamElemCurv (beamelem,mbeam[k],VIS_NODATA,NULL,VIS_NODATA,NULL); GLWinXfmPop (glwin); GLWinSwap (glwin); sleep(1); } } sleep(5); /* free all objects */ vgl_DrawFunEnd (df); vis_VisContextEnd (vc); vis_ColorMapEnd (cmap); vis_LevelsEnd (levels); vis_BeamSectEnd (beamsect); vis_BeamElemEnd (beamelem); GLWinEnd (glwin); return 0; }
The laminate properties are computed by calling vis_ShellWallProps. The shell wall is drawn by calling vis_ShellWallDraw. The appropriate flags have been enabled in the VisContext attribute object to draw a colored line for each layer. The orientation of the local material coordinate system for each layer is drawn by default, the drawing of the basic local coordinate system axes is enabled by calling vis_ShellWallSetParami.
#include "base/base.h" #include "vgl/vgl.h" #include "vis/vis.h" #include "glwin.h" static Vfloat rgb[9][3] = { {.5,.5,.5}, {1.,0.,0.}, {0.,1.,0.}, {0.,0.,1.}, {0.,1.,1.}, {1.,0.,1.}, {1.,1.,0.}, {.2,.2,.2}, {1.,1.,1.} }; static Vfloat xtex[3] = { -.8, .8, 0. }; static Vfloat ctex[3] = { 1., 1., 1. }; /*---------------------------------------------------------------------- Compute and Draw 3-Layer Shell Wall ----------------------------------------------------------------------*/ int main() { vgl_DrawFun *df; vis_VisContext *vc; vis_ColorMap *cmap; vis_Levels *levels; vis_ShellWall *shellwall; GLWin *glwin; Vint i; Vfloat x[3], tm[3][3]; Vint nlayers = 3; Vfloat zp[4] = { 0.,.2,.6,.8 }; Vint ix[2]; Vfloat phi[3] = { -45.,0.,-45. }; Vfloat mprop[6]; /* create GL device */ glwin = GLWinBegin (); GLWinCreateWindow (glwin,200,200,400,400); GLWinOrtho (glwin,-1.,1.,-1.,1.,-1.,1.); /* create draw function object for GL */ df = vgl_DrawFunBegin (); GLWinDrawFun (glwin,df); vc = vis_VisContextBegin (); vis_VisContextSetABCColor (vc,0,0,0); vis_VisContextSetXYZColor (vc,4,5,6); vis_VisContextSetLineWidth (vc,2); vis_VisContextSetMinorLineWidth (vc,2); vis_VisContextSetSize (vc,.4); vis_VisContextSetMapColor (vc,VIS_ON); /* levels for shell wall */ levels = vis_LevelsBegin (); vis_LevelsDef (levels,LEVELS_LINEAR,7); /* color map */ cmap = vis_ColorMapBegin (); vis_ColorMapSetType (cmap,COLORMAP_TRUECOLOR); vis_ColorMapSetRGB (cmap,9,0,rgb); /* create shellwall object and set objects */ shellwall = vis_ShellWallBegin (); vis_ShellWallSetObject (shellwall,VGL_DRAWFUN,df); vis_ShellWallSetObject (shellwall,VIS_VISCONTEXT,vc); vis_ShellWallSetObject (shellwall,VIS_COLORMAP,cmap); vis_ShellWallSetObject (shellwall,VIS_LEVELS,levels); vis_ShellWallSetParami (shellwall,SHELLWALL_AXESBASIC,SYS_ON); /* define 3 layer laminate */ vis_ShellWallDef (shellwall,SHELLWALL_GEOMETRY); for(i = 1; i <= nlayers+1; i++) { vis_ShellWallSetPoint (shellwall,i,zp[i-1]); } for(i = 1; i <= nlayers; i++) { ix[0] = i; ix[1] = i+1; vis_ShellWallSetLayer (shellwall,i,ix,phi[i-1],1); } /* define lamina material id 1 */ mprop[0] = 1000000.; mprop[1] = 2000000.; mprop[2] = .1; mprop[3] = 500000.; mprop[4] = 500000.; mprop[5] = 500000.; vis_ShellWallSetElasProp (shellwall,1,VIS_MAT_LAMINA,mprop); /* compute wall properties */ vis_ShellWallProps (shellwall); /* set position */ x[0] = 0.; x[1] = 0.; x[2] = 0.; /* set orientation - x' out, y' right, z' up */ tm[0][0] = 0.; tm[0][1] = 0.; tm[0][2] = 1.; tm[1][0] = 1.; tm[1][1] = 0.; tm[1][2] = 0.; tm[2][0] = 0.; tm[2][1] = 1.; tm[2][2] = 0.; /* draw */ GLWinClear (glwin); GLWinColor (glwin,ctex); GLWinText (glwin,xtex,"3 Layer Shell Wall"); GLWinRotate (glwin,20.,'x'); GLWinRotate (glwin,60.,'y'); vis_ShellWallDraw (shellwall,x,tm); GLWinSwap (glwin); sleep(5); /* free all objects */ vgl_DrawFunEnd (df); vis_VisContextEnd (vc); vis_ColorMapEnd (cmap); vis_LevelsEnd (levels); vis_ShellWallEnd (shellwall); GLWinEnd (glwin); return 0; }
The six node topology is set using vis_ShellElemSetTopology. A call to vis_ShellElemSetCornerFactors defines the overall laminate scale factors at the shell corner points. The laminate scaling is performed linearly between the shell element corner points. The shell element is drawn in five sequences illustrating various combinations of the ElemRep and ElemLoc visualization contexts and enabling the SHELLELEM_WALL parameter.
When drawing assemblies of curved shells it is essential to supply the exact shell node normals to the call to vis_ShellElemCurv. This ensures that the reconstructed top and bottom surfaces of adjacent shells are conformal. It is also highly recommended to avoid drawing the edges of shell elements which are mated to an adjacent shell and will be obscured by the top and bottom surfaces of the shells. Only the visible edges of shells need be drawn. Use vis_ShellElemSetEdgeFlag to flag only those edges to be drawn.
#include "base/base.h" #include "vgl/vgl.h" #include "vis/vis.h" #include "glwin.h" static Vfloat rgb[9][3] = { {.5,.5,.5}, {1.,0.,0.}, {0.,1.,0.}, {0.,0.,1.}, {0.,1.,1.}, {1.,0.,1.}, {1.,1.,0.}, {.2,.2,.2}, {1.,1.,1.} }; static Vfloat xtex[3] = { -.8, 2.8, 0. }; static Vfloat ctex[3] = { 1., 1., 1. }; /* cylindrical shell midsurface coordinates */ static Vfloat xshell[6][3] = { {0.,0.,0.}, {2.,0.,0.}, {0.,1.,1.}, {1.,0.,0.}, {1.,.7071,.2928}, {0.,.7071,.2928} }; /* shell midsurface normals */ static Vfloat vshell[6][3] = { {0.,0.,1.}, {0.,0.,1.}, {0.,-1.,0.}, {0.,0.,1.}, {0.,-.7071,.7071}, {0.,-.7071,.7071} }; /*---------------------------------------------------------------------- Draw 3-Layer Parabolic Triangular Shell Element ----------------------------------------------------------------------*/ int main() { vgl_DrawFun *df; vis_VisContext *vc; vis_ColorMap *cmap; vis_Levels *levels; vis_ShellElem *shellelem; vis_ShellWall *shellwall; GLWin *glwin; Vint i, j; Vfloat factors[3]; Vint nlayers = 3; Vfloat zp[4] = { 0.,.02,.06,.08 }; Vint ix[2]; Vfloat phi[3] = { -45.,0.,-45. }; Vfloat mprop[6]; /* create GL device */ glwin = GLWinBegin (); GLWinCreateWindow (glwin,200,200,600,600); GLWinOrtho (glwin,-.5,2.5,-.5,2.5,-10.,10.); /* create draw function object for GL */ df = vgl_DrawFunBegin (); GLWinDrawFun (glwin,df); vc = vis_VisContextBegin (); /* surfaces gray */ vis_VisContextSetColor (vc,0); vis_VisContextSetMinorColor (vc,0); vis_VisContextSetABCColor (vc,0,0,0); vis_VisContextSetXYZColor (vc,1,2,3); vis_VisContextSetFill (vc,VIS_ON); vis_VisContextSetEdge (vc,VIS_OFF); vis_VisContextSetSize (vc,.4); vis_VisContextSetMapColor (vc,VIS_ON); vis_VisContextSetRefinement (vc,2); vis_VisContextSetScale (vc,2.); vis_VisContextSetShade (vc,VIS_VERTEXSHADE); vis_VisContextSetElemRep (vc,VIS_ELEMREP_SOLID); /* levels for shell wall */ levels = vis_LevelsBegin (); vis_LevelsDef (levels,LEVELS_LINEAR,7); /* color map */ cmap = vis_ColorMapBegin (); vis_ColorMapSetType (cmap,COLORMAP_TRUECOLOR); vis_ColorMapSetRGB (cmap,9,0,rgb); /* create shellwall object and set objects */ shellwall = vis_ShellWallBegin (); vis_ShellWallSetObject (shellwall,VGL_DRAWFUN,df); vis_ShellWallSetObject (shellwall,VIS_VISCONTEXT,vc); vis_ShellWallSetObject (shellwall,VIS_COLORMAP,cmap); vis_ShellWallSetObject (shellwall,VIS_LEVELS,levels); vis_ShellWallSetParami (shellwall,SHELLWALL_AXESBASIC,SYS_ON); /* define 3 layer laminate */ vis_ShellWallDef (shellwall,SHELLWALL_GEOMETRY); for(i = 1; i <= nlayers+1; i++) { vis_ShellWallSetPoint (shellwall,i,zp[i-1]); } for(i = 1; i <= nlayers; i++) { ix[0] = i; ix[1] = i+1; vis_ShellWallSetLayer (shellwall,i,ix,phi[i-1],1); } /* define lamina material id 1 */ mprop[0] = 1000000.; mprop[1] = 2000000.; mprop[2] = .1; mprop[3] = 500000.; mprop[4] = 500000.; mprop[5] = 500000.; vis_ShellWallSetElasProp (shellwall,1,VIS_MAT_LAMINA,mprop); /* compute wall properties */ vis_ShellWallProps (shellwall); /* create shell object and set objects */ shellelem = vis_ShellElemBegin (); vis_ShellElemSetObject (shellelem,VGL_DRAWFUN,df); vis_ShellElemSetObject (shellelem,VIS_VISCONTEXT,vc); vis_ShellElemSetObject (shellelem,VIS_COLORMAP,cmap); vis_ShellElemSetObject (shellelem,VIS_SHELLWALL,shellwall); vis_ShellElemSetParami (shellelem,SHELLELEM_WALL,VIS_ON); vis_ShellElemSetTopology (shellelem,VIS_SHAPETRI,3,0); factors[0] = 1.; factors[1] = 1.5; factors[2] = 1.75; vis_ShellElemSetCornerFactors (shellelem,factors); /* draw */ for(j = 0; j < 5; j++) { if(j == 0) { vis_VisContextSetElemLoc (vc,VIS_ELEMLOC_CENTROID); vis_VisContextSetElemRep (vc,VIS_ELEMREP_SEMI); } else if(j == 1) { vis_VisContextSetElemLoc (vc,VIS_ELEMLOC_CORNERS); vis_VisContextSetElemRep (vc,VIS_ELEMREP_SEMI); } else if(j == 2) { vis_VisContextSetElemLoc (vc,VIS_ELEMLOC_NODES); vis_VisContextSetElemRep (vc,VIS_ELEMREP_SEMI); /* bottom surface green, top surface red */ } else if(j == 3) { vis_VisContextSetColor (vc,1); vis_VisContextSetMinorColor (vc,2); vis_VisContextSetElemRep (vc,VIS_ELEMREP_SOLID); vis_ShellElemSetParami (shellelem,SHELLELEM_WALL,VIS_OFF); } else if(j == 4) { vis_VisContextSetColor (vc,0); vis_VisContextSetMinorColor (vc,0); vis_VisContextSetElemRep (vc,VIS_ELEMREP_SOLID); vis_ShellElemSetParami (shellelem,SHELLELEM_WALL,VIS_ON); } for(i = 0; i < 10; i++) { GLWinClear (glwin); GLWinColor (glwin,ctex); GLWinText (glwin,xtex,"3 Layer Shell Element"); GLWinXfmPush (glwin); GLWinRotate (glwin, i*4.,'x'); GLWinRotate (glwin, i*11.,'y'); /* draw shell using exact normals */ vis_ShellElemCurv (shellelem,xshell,VIS_VERTEXDATA,vshell); GLWinXfmPop (glwin); GLWinSwap (glwin); sleep(1); } } sleep(5); /* free all objects */ vgl_DrawFunEnd (df); vis_VisContextEnd (vc); vis_ColorMapEnd (cmap); vis_LevelsEnd (levels); vis_ShellWallEnd (shellwall); vis_ShellElemEnd (shellelem); GLWinEnd (glwin); return 0; }
The Connect object is used to generate an element edge group of the free faces of the two connected shell elements. This group will be used to avoid contouring any interior edges of the shell model. The basic geometry of the shell is represented by the shell midsurface coordinates and a shell thickness. The shell bottom and top surface coordinates are computed and the scalar field to be contoured is simply the x coordinate for the bottom surface and the x coordinate plus .5 for the top surface. Notice that when contouring the bottom surface the VisContext reflect flag is enabled so that the generated graphics primitives have their normals pointing out of the shell. The edges of the shells are contoured as quadrilateral faces which are parabolic in one direction and linear in the thickness direction. The vis_ConnectElemCnn function is useful for returning the locations of the shell edge data from the shell element arrays so that the correct values can be gathered for the bottom and top surfaces of the edge.
The cutting plane is generated in the usual way using the DataInt object to supply the Threshold object with the pointer to the data to be contoured. The dfC drawing function is registered in Threshold so that the graphics primitives with scalar data interpolated to their verices are sent to the appropriate contouring function. The topology used by Threshold in this case is a wedge with the data at the bottom surface nodes first followed by the data at the top surface nodes. Note that the Levels object associated with the cutting plane has a single level whose value is the y coordinate of the cutting plane. The scalar values input to vis_ThresholdCurv in this case are the y coordinates of the vertices of the wedge reconstruction of the 3D triangular shell element.
#include "base/base.h" #include "vgl/vgl.h" #include "vis/vis.h" #include "glwin.h" static Vfloat rgb[9][3] = { {.5,.5,.5}, {1.,0.,0.}, {0.,1.,0.}, {0.,0.,1.}, {0.,1.,1.}, {1.,0.,1.}, {1.,1.,0.}, {.2,.2,.2}, {1.,1.,1.} }; /* two 6 node triangular shell elements 7---8---9 | \ | 4---5---6 | \ | 1---2---3 */ /* midsurface node coordinates */ static Vfloat xmid[9][3] = { {0.,0.,0.}, {1.,0.,0.}, {2.,0.,0.}, {0.,1.,0.}, {1.,1.,0.}, {2.,1.,0.}, {0.,2.,0.}, {1.,2.,0.}, {2.,2.,0.} }; /* midsurface normals, all in z direction */ static Vfloat vmid[9][3] = { {0.,0.,1.}, {0.,0.,1.}, {0.,0.,1.}, {0.,0.,1.}, {0.,0.,1.}, {0.,0.,1.}, {0.,0.,1.}, {0.,0.,1.}, {0.,0.,1.} }; /* shell element connectivity */ static Vint scon[2][6] = { {1,3,7, 2,5,4}, {3,9,7, 6,8,5} }; /*---------------------------------------------------------------------- Contour Plot and Cutting Plane 3D Monocoque Shell Elements ----------------------------------------------------------------------*/ int main() { vgl_DrawFun *df, *dfC; vis_VisContext *vc; vis_ColorMap *cmap; vis_Levels *levels; vis_Contour *contour; vis_VisContext *vct; vis_Levels *levelst; vis_Threshold *threshold; vis_DataInt *dataint; GLWin *glwin; vis_Connect *connect; vis_Group *group; Vint i, j, k, m, n; Vfloat xbt[2][6][3], sbt[2][6]; Vfloat xedge[6][3], sedge[6]; Vfloat sth[2][6]; Vint numelem, numnode; Vint flag, nix, in[3], nn; Vfloat thick = .25; /* create GL device */ glwin = GLWinBegin (); GLWinCreateWindow (glwin,200,200,400,400); GLWinOrtho (glwin,-3.,3.,-3.,3.,-10.,10.); /* create draw function object for GL */ df = vgl_DrawFunBegin (); GLWinDrawFun (glwin,df); /* load shell model into Connect object */ numnode = 9; numelem = 2; connect = vis_ConnectBegin(); vis_ConnectDef (connect,numnode,numelem); /* load nodes */ for(i = 1; i <= numnode; i++) { vis_ConnectSetCoords (connect,i,xmid[i-1]); } /* load element connectivity */ for(i = 1; i <= numelem; i++) { vis_ConnectSetTopology (connect,i,VIS_SHAPETRI,3,0,0); vis_ConnectSetElemNode (connect,i,scon[i-1]); } /* form kernel for adjacency related queries */ vis_ConnectKernel (connect,0); /* generate element edge group of free edges */ group = vis_GroupBegin(); vis_GroupDef (group,numelem,SYS_ELEM,SYS_EDGE); vis_ConnectEdgeGroup (connect,CONNECT_FREE,NULL,group); vc = vis_VisContextBegin (); vis_VisContextSetIsoValType (vc,VIS_ISOVALFRINGE); vis_VisContextSetMapColor (vc,VIS_ON); vis_VisContextSetShade (vc,VIS_VERTEXSHADE); /* color map */ cmap = vis_ColorMapBegin (); vis_ColorMapSetType (cmap,COLORMAP_TRUECOLOR); vis_ColorMapSetRGB (cmap,9,0,rgb); /* levels object for contouring, 6 levels*/ levels = vis_LevelsBegin (); vis_LevelsDef (levels,LEVELS_LINEAR,6); vis_LevelsSetMinMax (levels,0.,2.5); vis_LevelsGenerate (levels,LEVELS_PADTOP); /* contour object */ contour = vis_ContourBegin(); vis_ContourSetObject (contour,VGL_DRAWFUN,df); vis_ContourSetObject (contour,VIS_VISCONTEXT,vc); vis_ContourSetObject (contour,VIS_COLORMAP,cmap); vis_ContourSetObject (contour,VIS_LEVELS,levels); /* rotate 30 times */ for(k = 0; k < 15; k++) { GLWinClear (glwin); GLWinXfmPush (glwin); GLWinRotate (glwin,-k*4.,'x'); GLWinRotate (glwin,-k*10.,'y'); /* loop through elements */ for(i = 1; i <= numelem; i++) { /* bottom and top surfaces */ vis_ContourSetTopology (contour,VIS_SHAPETRI,3,0); for(j = 0; j < 6; j++) { nn = scon[i-1][j]; xbt[0][j][0] = xmid[nn-1][0] - vmid[nn-1][0]*.5*thick; xbt[0][j][1] = xmid[nn-1][1] - vmid[nn-1][1]*.5*thick; xbt[0][j][2] = xmid[nn-1][2] - vmid[nn-1][2]*.5*thick; sbt[0][j] = xbt[0][j][0]; xbt[1][j][0] = xmid[nn-1][0] + vmid[nn-1][0]*.5*thick; xbt[1][j][1] = xmid[nn-1][1] + vmid[nn-1][1]*.5*thick; xbt[1][j][2] = xmid[nn-1][2] + vmid[nn-1][2]*.5*thick; sbt[1][j] = xbt[1][j][0]+.5; } /* turn on reflect for bottom */ vis_VisContextSetReflect (vc,VIS_ON); vis_ContourCurv (contour,sbt[0],xbt[0],VIS_NODATA,NULL); /* turn off reflect for top */ vis_VisContextSetReflect (vc,VIS_OFF); vis_ContourCurv (contour,sbt[1],xbt[1],VIS_NODATA,NULL); /* now loop through 3 edges */ /* the edge is a quad face parabolic in one direction and linear in the other */ vis_ContourSetTopology (contour,VIS_SHAPEQUAD,3,2); for(m = 1; m <= 3; m++) { /* test to only draw free edges */ flag = vis_GroupElemEnt (group,i,m); if(flag == 0) continue; /* get locations of edge data in element arrays */ vis_ConnectElemCnn (connect,SYS_EDGE,i,m,&nix,in); /* set bottom data first and then top data */ for(n = 0; n < 3; n++) { xedge[n][0] = xbt[0][in[n]-1][0]; xedge[n][1] = xbt[0][in[n]-1][1]; xedge[n][2] = xbt[0][in[n]-1][2]; sedge[n] = sbt[0][in[n]-1]; xedge[3+n][0] = xbt[1][in[n]-1][0]; xedge[3+n][1] = xbt[1][in[n]-1][1]; xedge[3+n][2] = xbt[1][in[n]-1][2]; sedge[3+n] = sbt[1][in[n]-1]; } vis_ContourCurv (contour,sedge,xedge,VIS_NODATA,NULL); } } GLWinXfmPop (glwin); GLWinSwap (glwin); GLWinDelay (glwin,1.); } /* viscontext for threshold */ vct = vis_VisContextBegin (); vis_VisContextSetIsoValType (vct,VIS_ISOVALSURFACE); vis_VisContextSetShade (vc,VIS_VERTEXSHADE); /* levels object for threshold 1 level*/ /* the cutting plane is at y = .75 */ levelst = vis_LevelsBegin (); vis_LevelsDef (levelst,LEVELS_LINEAR,1); vis_LevelsSetValue (levelst,1,.75); /* data interpolation object for scalar field */ dataint = vis_DataIntBegin (); vis_DataIntSetDataPtr (dataint,0,1,(Vfloat*)sbt); /* create contouring drawing function object */ dfC = vgl_DrawFunBegin (); vgl_DrawFunSetObj (dfC,contour); vgl_DrawFunAPI (dfC,DRAWFUN_APIRETURN); /* use function provided by Contour module */ vgl_DrawFunSet (dfC,DRAWFUN_POLYGONDATA,(Vfunc*)vis_ContourPolygonData); /* threshold object */ threshold = vis_ThresholdBegin(); vis_ThresholdSetObject (threshold,VGL_DRAWFUN,dfC); vis_ThresholdSetObject (threshold,VIS_VISCONTEXT,vct); vis_ThresholdSetObject (threshold,VIS_COLORMAP,cmap); vis_ThresholdSetObject (threshold,VIS_LEVELS,levelst); vis_ThresholdSetObject (threshold,VIS_DATAINT,dataint); /* rotate 30 times */ for(k = 0; k < 15; k++) { GLWinClear (glwin); GLWinXfmPush (glwin); GLWinRotate (glwin,-k*4.,'x'); GLWinRotate (glwin,-k*10.,'y'); /* the 3D shell is respresented as a wedge */ vis_ThresholdSetTopology (threshold,VIS_SHAPEWED,3,0,2); /* loop through elements */ for(i = 1; i <= numelem; i++) { /* bottom and top surfaces */ /* sth array holds y coordinates */ for(j = 0; j < 6; j++) { nn = scon[i-1][j]; xbt[0][j][0] = xmid[nn-1][0] - vmid[nn-1][0]*.5*thick; xbt[0][j][1] = xmid[nn-1][1] - vmid[nn-1][1]*.5*thick; xbt[0][j][2] = xmid[nn-1][2] - vmid[nn-1][2]*.5*thick; sbt[0][j] = xbt[0][j][0]; sth[0][j] = xbt[0][j][1]; xbt[1][j][0] = xmid[nn-1][0] + vmid[nn-1][0]*.5*thick; xbt[1][j][1] = xmid[nn-1][1] + vmid[nn-1][1]*.5*thick; xbt[1][j][2] = xmid[nn-1][2] + vmid[nn-1][2]*.5*thick; sbt[1][j] = xbt[1][j][0]+.5; sth[1][j] = xbt[1][j][1]; } vis_ThresholdCurv (threshold,(Vfloat*)sth,(Vfloat(*)[3])xbt, VIS_NODATA,NULL); } GLWinXfmPop (glwin); GLWinSwap (glwin); GLWinDelay (glwin,1.); } /* free all objects */ vgl_DrawFunEnd (df); vis_VisContextEnd (vc); vis_ColorMapEnd (cmap); vis_LevelsEnd (levels); vis_ContourEnd (contour); vgl_DrawFunEnd (dfC); vis_VisContextEnd (vct); vis_LevelsEnd (levelst); vis_ThresholdEnd (threshold); vis_ConnectEnd (connect); vis_GroupEnd (group); GLWinEnd (glwin); return 0; }
The second billboard illustrates drawing wide character strings with the vis_BillboardTextItemtv function. The underlying graphics system must accept wide character strings. In this case VisTools and VglTools must be compiled with VKI_WIDECHAR defined. A window system raster font is used which supports wide characters.
The ColorMap module function vis_ColorMapRamp is used with COLORMAP_SET to provide a useful set of named colors for coloring and shading the billboard.
#include "base/base.h" #include "vgl/vgl.h" #include "vis/vis.h" /*---------------------------------------------------------------------- Draw a Simple Billboard ----------------------------------------------------------------------*/ int main() { #ifdef VKI_WIND_X11 Display *display; int screen; #else HFONT hfont; #endif vgl_DrawFun *df; vis_VisContext *vc; vis_ColorMap *cmap; vis_Billboard *billboard; vgl_OpenGLDev *ogldev; vgl_RasFont *rasfont; #ifdef VKI_WIDECHAR static Vtchar euro[] = { L'U',L'n',L'i',L'c',L'o',L'd',L'e',L' ',L'E',L'u',L'r',L'o',L'=',L' ', 0x20ac,L'\0'}; #else static Vtchar euro[] = "Unicode Euro= euro"; #endif Vfloat x[3]; #ifdef VKI_WIND_X11 display = XOpenDisplay (0); screen = DefaultScreen (display); vgl_OpenGLDevConnectX (display,screen); #endif #ifdef VKI_WIND_WIN32 vgl_OpenGLDevConnectWIN (); #endif /* create GL device */ ogldev = vgl_OpenGLDevBegin (); /* create draw function object for GL */ df = vgl_DrawFunBegin (); vgl_OpenGLDevDrawFun (ogldev,df); vgl_DrawFunPositionWindow (df,200,200,400,400); vgl_DrawFunOpenWindow (df,"Example 15vgl"); vgl_DrawFunProjOrtho (df,-2.,2.,-2.,2.,-2.,2.); vgl_DrawFunSetMode (df,VGL_ZBUFFERMODE,VGL_ON); rasfont = vgl_RasFontBegin(); #ifdef VKI_WIND_X11 vgl_RasFontLoadXFont (rasfont,display, "-adobe-courier-bold-o-normal--14-100-100-100-m-90-iso10646-1"); #else hfont = CreateFont(15,9,0,0,0,0,0,0,0,0,0,0,FIXED_PITCH|FF_DONTCARE, TEXT("Arial")); vgl_RasFontLoadWINFont (rasfont,hfont); #endif vgl_DrawFunRasFontDefine (df,1,rasfont); /* color map, standard set of 29 colors */ cmap = vis_ColorMapBegin (); vis_ColorMapSetType (cmap,COLORMAP_TRUECOLOR); vis_ColorMapRamp (cmap,29,0,COLORMAP_SET); /* vis context and set attributes */ vc = vis_VisContextBegin (); vis_VisContextSetMapColor (vc,VIS_OFF); vis_VisContextSetColor (vc,COLORMAP_SET_GRAY40); vis_VisContextSetABCColor (vc,COLORMAP_SET_RED, COLORMAP_SET_REDDARK, COLORMAP_SET_REDLITE); /* create billboard object */ billboard = vis_BillboardBegin (); vis_BillboardSetObject (billboard,VGL_DRAWFUN,df); vis_BillboardSetObject (billboard,VIS_COLORMAP,cmap); vis_BillboardSetObject (billboard,VIS_VISCONTEXT,vc); /* enter contents of billboard */ vis_BillboardSetItemParami (billboard,BILLBOARD_COLOR,COLORMAP_SET_BLUE); /* title automatically generate a new line */ vis_BillboardTitleItem (billboard, "Analysis Results"); vis_BillboardSetItemParami (billboard,BILLBOARD_COLOR,COLORMAP_SET_WHITE); vis_BillboardSetItemParami (billboard,BILLBOARD_SHADOW_COLOR, COLORMAP_SET_GRAY20); vis_BillboardSetItemParami (billboard,BILLBOARD_RULE_BEVEL,VIS_ON); /* rule automatically generate a new line */ vis_BillboardRuleItem (billboard); vis_BillboardSetItemParami (billboard,BILLBOARD_COLOR,COLORMAP_SET_CYAN); vis_BillboardTextItem (billboard, "stress_xx = 10230.\n"); vis_BillboardTextItem (billboard, "stress_yy = 15328.\n"); vis_BillboardTextItem (billboard, "stress_zz = 556.\n"); vis_BillboardSetItemParami (billboard,BILLBOARD_COLOR,COLORMAP_SET_BLACK); vis_BillboardSetItemParami (billboard,BILLBOARD_RULE_BEVEL,VIS_OFF); vis_BillboardSetItemParami (billboard,BILLBOARD_LINE_STYLE,VIS_DASHDASH); vis_BillboardRuleItem (billboard); vis_BillboardSetItemParami (billboard,BILLBOARD_COLOR,COLORMAP_SET_YELLOW); vis_BillboardTextItem (billboard, "strain_xx = .00121\n"); vis_BillboardTextItem (billboard, "strain_yy = .00153\n"); /* do not want newline after last item */ vis_BillboardTextItem (billboard, "strain_zz = .00012"); /* define anchor point */ x[0] = -0.5; x[1] = -0.5; x[2] = 0.0; /* draw billboard */ vgl_DrawFunClear (df); vis_BillboardDraw (billboard,x); vgl_DrawFunSwap (df); vgl_DrawFunDelay (df,5.); /* draw billboard with wide character string */ vis_BillboardErase (billboard); vis_BillboardSetItemParami (billboard,BILLBOARD_COLOR,COLORMAP_SET_BLUE); vis_BillboardTitleItem (billboard,"Product Cost"); vis_BillboardRuleItem (billboard); vis_BillboardTextItemtv (billboard, euro); vgl_DrawFunRasFontSelect (df,1); vgl_DrawFunClear (df); vis_BillboardDraw (billboard,x); vgl_DrawFunSwap (df); vgl_DrawFunDelay (df,5.); /* close window */ vgl_DrawFunCloseWindow (df); /* free all objects */ vgl_DrawFunEnd (df); vgl_RasFontEnd (rasfont); vis_VisContextEnd (vc); vis_ColorMapEnd (cmap); vgl_OpenGLDevEnd (ogldev); vis_BillboardEnd (billboard); /* disconnect */ vgl_OpenGLDevDisconnect (); #ifdef VKI_WIND_X11 XCloseDisplay (display); #endif return 0; }
A Cell module is used to draw the wireframe of a hexahedron in yellow. The billboard is anchored to the fifth node of the hexahedron. A device offset is defined in the visualization context so that the billboard is offset up and to the right from the anchor point. A parameter is set using vis_BillboardSetParami to display an offset vector from the anchor point to the attachment position on the billboard - in this case the bottom left of the billboard. As the entire scene is rotated the billboard is transformed by the anchor point but remains the same size and oriented perpendicular to the viewer. Note that lighting is disabled immediately before the billboard is drawn using vis_BillboardDraw. Since billboards are essentially 2D annotation objects it is desirable to ensure that their base colors are not modified by lighting calculations. Lighting is re-enabled after the billboard is drawn.
#include "base/base.h" #include "vgl/vgl.h" #include "vis/vis.h" static Vfloat xhex[8][3] = { {-.5,-.5,-.5}, {.5,-.5,-.5}, {.5,.5,-.5}, {-.5,.5,-.5}, {-.5,-.5,.5}, {.5,-.5,.5}, {.5,.5,.5}, {-.5,.5,.5} }; /*---------------------------------------------------------------------- Draw a Fancy Billboard ----------------------------------------------------------------------*/ int main() { #ifdef VKI_WIND_X11 Display *display; int screen; #endif vgl_DrawFun *df; vis_VisContext *vc, *vccell; vis_ColorMap *cmap; vis_Billboard *billboard; vis_Cell *cell; vgl_OpenGLDev *ogldev; vgl_Xfm *xfm; int i; Vfloat offset[2]; Vchar str[80]; Vfloat width, height; Vfloat c[3], x[3], tm[4][4]; #ifdef VKI_WIND_X11 display = XOpenDisplay (0); screen = DefaultScreen (display); vgl_OpenGLDevConnectX (display,screen); #endif #ifdef VKI_WIND_WIN32 vgl_OpenGLDevConnectWIN (); #endif /* create GL device */ ogldev = vgl_OpenGLDevBegin (); /* create draw function object for GL */ df = vgl_DrawFunBegin (); vgl_OpenGLDevDrawFun (ogldev,df); vgl_DrawFunPositionWindow (df,100,100,800,800); vgl_DrawFunOpenWindow (df,"Example 15avgl"); vgl_DrawFunProjOrtho (df,-1.,2.,-1.,2.,-1.,2.); vgl_DrawFunSetMode (df,VGL_ZBUFFERMODE,VGL_ON); vgl_DrawFunSetMode (df,VGL_LIGHTMODE,VGL_ON); c[0] = .4; c[1] = .4; c[2] = .4; x[0] = 0.; x[1] = 0.; x[2] = 0.; vgl_DrawFunLight (df,0,VGL_LIGHT_AMBIENT,c,x); c[0] = .6; c[1] = .6; c[2] = .6; x[0] = 1.; x[1] = 1.; x[2] = 1.; vgl_DrawFunLight (df,1,VGL_LIGHT_DISTANT,c,x); x[0] = -1.; x[1] = -1.; x[2] = -1.; vgl_DrawFunLight (df,2,VGL_LIGHT_DISTANT,c,x); /* create transformation object */ xfm = vgl_XfmBegin (); /* color map, standard set of 29 colors */ cmap = vis_ColorMapBegin (); vis_ColorMapSetType (cmap,COLORMAP_TRUECOLOR); vis_ColorMapRamp (cmap,29,0,COLORMAP_SET); /* vis context and set attributes */ vccell = vis_VisContextBegin (); vis_VisContextSetMapColor (vccell,VIS_OFF); vis_VisContextSetColor (vccell,COLORMAP_SET_YELLOW); vis_VisContextSetFill (vccell,VIS_OFF); vis_VisContextSetEdge (vccell,VIS_ON); vis_VisContextSetLineStyle (vccell,VIS_CYLINDER); vis_VisContextSetSize (vccell,.025); /* create cell object */ cell = vis_CellBegin (); vis_CellSetObject (cell, VGL_DRAWFUN, df); vis_CellSetObject (cell, VIS_COLORMAP, cmap); vis_CellSetObject (cell, VIS_VISCONTEXT, vccell); /* vis context and set attributes */ vc = vis_VisContextBegin (); vis_VisContextSetMapColor (vc,VIS_OFF); vis_VisContextSetColor (vc,COLORMAP_SET_GRAY40); vis_VisContextSetMinorColor (vc,COLORMAP_SET_WHITE); vis_VisContextSetABCColor (vc,COLORMAP_SET_GRAY50, COLORMAP_SET_GRAY30, COLORMAP_SET_GRAY70); vis_VisContextSetDeviceOffset (vc,40,10); /* create billboard object */ billboard = vis_BillboardBegin (); vis_BillboardSetObject (billboard, VGL_DRAWFUN, df); vis_BillboardSetObject (billboard, VIS_COLORMAP, cmap); vis_BillboardSetObject (billboard, VIS_VISCONTEXT, vc); /* enter contents of billboard */ vis_BillboardSetItemParami (billboard,BILLBOARD_COLOR,COLORMAP_SET_BLUE); vis_BillboardTitleItem (billboard,"Custom"); vis_BillboardTitleItem (billboard,"Color Legend"); vis_BillboardSetItemParami (billboard,BILLBOARD_COLOR,COLORMAP_SET_GRAY70); vis_BillboardSetItemParami (billboard,BILLBOARD_SHADOW_COLOR, COLORMAP_SET_GRAY30); vis_BillboardRuleItem (billboard); vis_BillboardNewLine (billboard, 2.0); width = 4.0; height = 2.5; /* add a series of colored boxes for a legend */ for(i = 0; i < 6; i++) { sprintf (str, "value %d", i+1); vis_BillboardSetItemParami (billboard,BILLBOARD_COLOR,COLORMAP_SET_RED+i); vis_BillboardRectangleItem (billboard, width, height, 1); /* backspace to outline in black */ vis_BillboardSpace (billboard, -width); vis_BillboardSetItemParami (billboard,BILLBOARD_COLOR,COLORMAP_SET_BLACK); vis_BillboardRectangleItem (billboard, width, height, 0); /* offset to draw text after rectangle */ offset[0] = 2.0; offset[1] = 1.0; vis_BillboardSetItemParamfv (billboard,BILLBOARD_OFFSET,offset); vis_BillboardSetItemParami (billboard,BILLBOARD_COLOR,COLORMAP_SET_RED+i); vis_BillboardTextItem (billboard, str); offset[0] = 0.0; offset[1] = 0.0; vis_BillboardSetItemParamfv (billboard,BILLBOARD_OFFSET,offset); if (i != 5) { vis_BillboardNewLine (billboard, height); } } /* turn on drawing of offset vector */ vis_BillboardSetParami (billboard,BILLBOARD_OFFSET_VECTOR,VIS_ON); /* draw billboard and wireframe cell */ for(i = 0; i < 340; i++) { vgl_DrawFunClear (df); vgl_DrawFunXfmPush (df); vgl_XfmRotate (xfm,i*.03,XFM_YAXIS); vgl_XfmGetMatrix (xfm,tm); vgl_DrawFunXfmLoad (df,tm); vgl_XfmRotate (xfm,i*.01,XFM_XAXIS); vgl_XfmGetMatrix (xfm,tm); vgl_DrawFunXfmMult (df,tm); vis_VisContextTouch (vccell); vis_CellCurv (cell, xhex); vis_VisContextTouch (vc); vgl_DrawFunSetMode (df,VGL_LIGHTMODE,VGL_OFF); vis_BillboardDraw (billboard, xhex[4]); vgl_DrawFunSetMode (df,VGL_LIGHTMODE,VGL_ON); vgl_DrawFunXfmPop (df); vgl_DrawFunSwap (df); vgl_DrawFunDelay (df,.05); } vgl_DrawFunDelay (df,5.); /* close window */ vgl_DrawFunCloseWindow (df); /* free all objects */ vgl_DrawFunEnd (df); vis_VisContextEnd (vc); vis_VisContextEnd (vccell); vis_ColorMapEnd (cmap); vgl_OpenGLDevEnd (ogldev); vgl_XfmEnd (xfm); vis_BillboardEnd (billboard); vis_CellEnd (cell); /* disconnect */ vgl_OpenGLDevDisconnect (); #ifdef VKI_WIND_X11 XCloseDisplay (display); #endif return 0; }
The center of the circular edge with its radius is annotated using a radius leader. The circular edge is also annotated on its back side with an angular dimension. The right side of the model is annotated as a contact surface using a leader line. The dimensioning module backplane flip option is enabled so that as the model rotates about the y-axis the dimensioning labels are always readable.
#include "base/base.h" #include "vgl/vgl.h" #include "vis/vis.h" #include "glwin.h" #define MAX_PTS 50 static Vfloat rgb[7][3] = { {.2,.2,.2}, {1.,0.,0.}, {0.,1.,0.}, {0.,0.,1.}, {0.,1.,1.}, {1.,0.,1.}, {1.,1.,0.} }; static Vfloat frnt_norm[3] = {0.0, 0.0, 1.0}; static Vfloat back_norm[3] = {0.0, 0.0, -1.0}; void create_outline(Vint *p_n, Vfloat outline[][2]); void draw_solid(vgl_DrawFun *df, Vint n, Vfloat outline[][2], Vfloat zf, Vfloat zb); /*---------------------------------------------------------------------- Generate dimension annotation for a solid ----------------------------------------------------------------------*/ int main() { vgl_DrawFun *df; vis_VisContext *vc; vis_ColorMap *cmap; GLWin *glwin; Vint i, n; Vfloat outline[MAX_PTS][2]; Vfloat view_mat[4][4]; Vfloat zf, zb; vis_Dimension *dimension; Vfloat up[3], right[3]; Vfloat x[3], xl[3], xlabel[3], xcenter[3]; Vfloat text_size = 0.35; Vfloat arrow_size = 1.5; /* create GL device */ glwin = GLWinBegin (); GLWinCreateWindow (glwin,200,200,600,600); GLWinOrtho (glwin,-14.,14.,-14.,14.,-14.,14.); /* create draw function object for GL */ df = vgl_DrawFunBegin (); GLWinDrawFun (glwin,df); /* vis context and set attributes */ vc = vis_VisContextBegin (); /* color map */ cmap = vis_ColorMapBegin (); vis_ColorMapSetType (cmap,COLORMAP_TRUECOLOR); vis_ColorMapSetRGB (cmap,16,0,rgb); vis_ColorMapValueDrawFun (cmap,df,1); /* create solid outline */ create_outline (&n,outline); zf = 2.5; zb = -2.5; /* dimension */ dimension = vis_DimensionBegin (); vis_DimensionSetObject (dimension,VGL_DRAWFUN,df); vis_DimensionSetObject (dimension,VIS_COLORMAP,cmap); vis_DimensionSetObject (dimension,VIS_VISCONTEXT,vc); right[0] = 1.0; right[1] = 0.0; right[2] = 0.0; up[0] = 0.0; up[1] = 1.0; up[2] = 0.0; vis_DimensionSetPlane (dimension, right, up); vis_VisContextSetColor (vc,2); vis_VisContextSetSize (vc,text_size); vis_VisContextSetMinorSize (vc,arrow_size); vis_VisContextSetMinorColor (vc,4); vis_VisContextSetFlags (vc,VIS_BACKPLANEFLIP); /* draw solid with dimensions */ for (i = 0; i < 36; i++) { GLWinClear (glwin); GLWinXfmPush (glwin); GLWinRotate (glwin,i*10.,'y'); GLWinXfmGet (glwin,view_mat); vis_VisContextSetXfmMatrix (vc,view_mat); vis_ColorMapValueDrawFun (cmap,df,1); draw_solid (df,n,outline,zf,zb); vis_VisContextSetVectorType (vc,VIS_VECTORLINE); vis_VisContextSetMinorColor (vc,4); vis_VisContextSetLineWidth (vc,1); /* linear vertical dimension */ x[0] = -5.0; x[1] = -5.0; x[2] = zf; xl[0] = -5.0; xl[1] = 0.0; xl[2] = zf; xlabel[0] = -7.0; xlabel[1] = 0.0; xlabel[2] = zf; vis_DimensionSetParami (dimension, DIMENSION_LABEL_ALIGN, DIMENSION_HORIZONTAL); vis_DimensionSetParami (dimension,DIMENSION_LINEAR_ALIGN, DIMENSION_VERTICAL); vis_DimensionLinear (dimension,x,xl,xlabel,"5"); /* linear horizontal dimension */ x[0] = 0.0; x[1] = 5.0; x[2] = zf; xl[0] = 5.0; xl[1] = 5.0; xl[2] = zf; xlabel[0] = 4.0; xlabel[1] = 7.0; xlabel[2] = zf; vis_DimensionSetParami (dimension, DIMENSION_LINEAR_ALIGN, DIMENSION_HORIZONTAL); vis_DimensionLinear (dimension,x,xl,xlabel,"5.0"); /* linear aligned dimension */ x[0] = -5.0; x[1] = 0.0; x[2] = zf; xl[0] = 0.0; xl[1] = 5.0; xl[2] = zf; xlabel[0] = -5.0; xlabel[1] = 5.0; xlabel[2] = zf; vis_DimensionSetParami (dimension, DIMENSION_LABEL_ALIGN, DIMENSION_ALIGNED); vis_DimensionSetParami (dimension, DIMENSION_LINEAR_ALIGN, DIMENSION_ALIGNED); vis_DimensionLinear (dimension,x,xl,xlabel,"7.071"); /* radius leader dimension */ x[0] = 1.465; x[1] = -1.465; x[2] = zf; xcenter[0] = 5.0; xcenter[1] = -5.0; xcenter[2] = zf; xlabel[0] = 8.0; xlabel[1] = -6.0; xlabel[2] = zf; vis_DimensionRadius (dimension,x,xcenter,xlabel,"5.0"); /* angular dimension */ x[0] = 5.0; x[1] = 0.0; x[2] = zb; xl[0] = 0.0; xl[1] = -5.0; xl[2] = zb; xcenter[0] = 5.0; xcenter[1] = -5.0; xcenter[2] = zb; xlabel[0] = 3.0; xlabel[1] = -3.0; xlabel[2] = zb; vis_DimensionSetParami (dimension, DIMENSION_LABEL_ALIGN, DIMENSION_ORTHOGONAL); vis_VisContextSetMinorLineStyle (vc,VIS_DASHDASH); vis_DimensionAngular (dimension,x,xl,xcenter,xlabel,"90 deg"); vis_VisContextSetMinorLineStyle (vc,VIS_SOLID); /* leader dimension */ vis_VisContextSetVectorType (vc,VIS_VECTORUMBRELLA); vis_VisContextSetMinorColor (vc,6); vis_VisContextSetLineWidth (vc,2); x[0] = 5.0; x[1] = 2.5; x[2] = 0.; xlabel[0] = 7.0; xlabel[1] = 4.0; xlabel[2] = 0.; vis_DimensionLeader (dimension,x,xlabel,"Contact Surface"); GLWinXfmPop (glwin); GLWinSwap (glwin); sleep(1); } sleep(2); /* free all objects */ vgl_DrawFunEnd (df); vis_VisContextEnd (vc); vis_ColorMapEnd (cmap); vis_DimensionEnd (dimension); GLWinEnd (glwin); return 0; } void create_outline(Vint *p_n, Vfloat outline[][2]) { Vint n, i, num_div; Vfloat r, begin_a, end_a, pi; Vfloat t, dt, cx, cy; /* Create an outline of a solid */ n = 0; outline[n][0] = -5.0; outline[n++][1] = -5.0; outline[n][0] = -5.0; outline[n++][1] = 0.0; outline[n][0] = 0.0; outline[n++][1] = 5.0; outline[n][0] = 5.0; outline[n++][1] = 5.0; outline[n][0] = 5.0; outline[n++][1] = 0.0; r = 5.0; num_div = 30; pi = 4.0 * atan (1.0); begin_a = pi / 2.0; end_a = pi; cx = 5.0; cy = -5.0; dt = (end_a - begin_a) / (Vfloat)num_div; t = begin_a + dt; for (i = 0; i < num_div; i++) { outline[n][0] = cx + r * cos(t); outline[n++][1] = cy + r * sin(t); t += dt; } *p_n = n; } void draw_solid(vgl_DrawFun *df, Vint n, Vfloat outline[][2], Vfloat zf, Vfloat zb) { Vint j, k, p, q; Vfloat pts[4][3]; Vfloat nx, ny, nz, norm[3], mag; /* Draw a solid extruded from an outline */ for (j = 0; j < n; j++) { k = j + 1; if (k >= n) { k = 0; } pts[0][0] = outline[j][0]; pts[0][1] = outline[j][1]; pts[0][2] = zf; pts[1][0] = outline[k][0]; pts[1][1] = outline[k][1]; pts[1][2] = zf; pts[2][0] = 0.0; pts[2][1] = 0.0; pts[2][2] = zf; vgl_DrawFunPolygon (df, VGL_POLYGON, 3, pts, VGL_FLATSHADE, frnt_norm); pts[0][2] = zb; pts[1][2] = zb; pts[2][2] = zb; vgl_DrawFunPolygon (df, VGL_POLYGON, 3, pts, VGL_FLATSHADE, back_norm); pts[0][2] = zf; pts[1][2] = zf; pts[2][0] = outline[k][0]; pts[2][1] = outline[k][1]; pts[2][2] = zb; pts[3][0] = outline[j][0]; pts[3][1] = outline[j][1]; pts[3][2] = zb; nx = ny = nz = 0.0; for (p = 0; p < 4; p++) { if (p == 3) { q = 0; } else { q = p + 1; } nx += pts[q][1]*pts[p][2] - pts[q][2]*pts[p][1]; ny += pts[q][2]*pts[p][0] - pts[q][0]*pts[p][2]; nz += pts[q][0]*pts[p][1] - pts[q][1]*pts[p][0]; } mag = sqrt (nx*nx + ny*ny + nz*nz); norm[0] = nx / mag; norm[1] = ny / mag; norm[2] = nz / mag; vgl_DrawFunPolygon (df, VGL_POLYGON, 4, pts, VGL_FLATSHADE, norm); } }
A new Cartesian system is defined using the computed rotation angle vector as the system orientation using the function vis_CoordSysSetOriginRotAng. The function vis_CoordSysOriginTriad is used to query the system orientation returning a direction cosine matrix. Note that this returned direction cosine matrix is identical to that returned by the previous call to vis_CoordSysDirCos, illustrating the equivalence of the rotation angle vector to the direction cosine matrix.
#include "base/base.h" #include "vgl/vgl.h" #include "vis/vis.h" #include "glwin.h" /*---------------------------------------------------------------------- Using Coordinate Systems ----------------------------------------------------------------------*/ int main() { vis_CoordSys *coordsys; vis_CoordSys *coordsysang; Vfloat x[3], tm[3][3]; Vfloat xp[3], tmp[3][3], xpl[3], rap[3]; Vfloat xa[3], tma[3][3]; Vfloat vp[3], vlc[3], vpc[3]; /* create Cylindrical CoordSys */ coordsys = vis_CoordSysBegin (); vis_CoordSysDef (coordsys,SYS_CYLINDRICAL); /* set origin at 10.,10.,0. */ x[0] = 10.; x[1] = 10.; x[2] = 0.; /* set orientation, x' along z, y' along x, z' along y */ tm[0][0] = 0.; tm[0][1] = 0.; tm[0][2] = 1.; tm[1][0] = 1.; tm[1][1] = 0.; tm[1][2] = 0.; tm[2][0] = 0.; tm[2][1] = 1.; tm[2][2] = 0.; vis_CoordSysSetOriginTriad (coordsys,x,tm); /* compute local direction cosines at point 20.,20.,10. */ xp[0] = 20.; xp[1] = 20.; xp[2] = 10.; vis_CoordSysDirCos (coordsys,xp,tmp); printf("x''= %f %f %f\n",tmp[0][0],tmp[0][1],tmp[0][2]); printf("y''= %f %f %f\n",tmp[1][0],tmp[1][1],tmp[1][2]); printf("z''= %f %f %f\n",tmp[2][0],tmp[2][1],tmp[2][2]); /* compute equivalent rotation angles of same system */ vis_CoordSysRotAng (coordsys,xp,rap); printf("\n"); printf("rx''= %f\n",rap[0]); printf("ry''= %f\n",rap[1]); printf("rz''= %f\n",rap[2]); /* define a new system using the computed rotation angles */ coordsysang = vis_CoordSysBegin (); vis_CoordSysDef (coordsysang,SYS_CARTESIAN); vis_CoordSysSetOriginRotAng (coordsysang,x,rap); /* query should match direction cosines */ vis_CoordSysOriginTriad (coordsysang,xa,tma); printf("\n"); printf("x''= %f %f %f\n",tma[0][0],tma[0][1],tma[0][2]); printf("y''= %f %f %f\n",tma[1][0],tma[1][1],tma[1][2]); printf("z''= %f %f %f\n",tma[2][0],tma[2][1],tma[2][2]); vis_CoordSysEnd (coordsysang); /* convert global coordinate to cylindrical coordinates */ vis_CoordSysConvertCoord (coordsys,xp,xpl); printf("\n"); printf("r = %f\n",xpl[0]); printf("theta= %f\n",xpl[1]); printf("z' = %f\n",xpl[2]); /* convert vector vp at xp to local Cartesian system */ vp[0] = 2.; vp[1] = 0.; vp[2] = 0.; vis_CoordSysConvertVector (coordsys,xp,vp,vlc); printf("\n"); printf("vlc= %f %f %f\n",vlc[0],vlc[1],vlc[2]); /* perform inverse. vpc should be same as original vp */ vis_CoordSysComputeVector (coordsys,xp,vlc,vpc); printf("\n"); printf("vpc= %f %f %f\n",vpc[0],vpc[1],vpc[2]); /* free object */ vis_CoordSysEnd (coordsys); return 0; }
The first type drawn is a distributing coupling (eg. NASTRAN RBE3). The special type is set using vis_RigidElemSetSpec with value SYS_RIGID_DIST. Typically all translations and rotations of the first node are dependent and all translations of subsequent nodes are independent. The topology should be SYS_SHAPEPOINT. For all point topologies, the icons are drawn as spokes radiating from the first node to the subsequent nodes. The spokes are Gouraud shaded from the Color at the first node to the MinorColor at the subsequent nodes. Note that weight sizing only requires the weight element properties in the EProp object.
The next type drawn is a kinematic coupling (eg. NASTRAN RBE2). The special type is set using vis_RigidElemSetSpec with value SYS_RIGID_KINE. All translations and rotations of the first node are independent and all translations of subsequent nodes are dependent. The topology should be SYS_SHAPEPOINT.
The next type drawn is a rigid link (eg. NASTRAN RROD). The special type is set using vis_RigidElemSetSpec with value SYS_RIGID_LINK. The topology should be SYS_SHAPELINE.
The next type drawn is a rigid triangular plate (eg. NASTRAN RTRPLT). The special type is set using vis_RigidElemSetSpec with value SYS_RIGID_KINE. The topology should be SYS_SHAPETRI.
The final type drawn is a multi-point constraint. The special type is set using vis_RigidElemSetSpec with value SYS_RIGID_MPC. The topology should be SYS_SHAPEPOINT. The first node is the dependent node and all subsequent nodes should be dependent. The weights are the coefficients of the constraint equation.
#include "base/base.h" #include "vgl/vgl.h" #include "vis/vis.h" #include "glwin.h" static Vfloat rgb[8][3] = { {.5,.5,.5}, {1.,0.,0.}, {0.,1.,0.}, {0.,0.,1.}, {0.,1.,1.}, {1.,0.,1.}, {1.,1.,0.}, {1.,1.,1.} }; static Vfloat xtex[3] = { -1.8, 1.5, 0. }; static Vfloat ctex[3] = { 1., 1., 1. }; void draw_elem(vgl_DrawFun *df, vis_RigidElem *rigidelem, Vfloat x[][3], Vchar *text); void rotate_elem(vgl_DrawFun *df, vis_RigidElem *rigidelem, Vfloat x[][3], Vchar *text); /*---------------------------------------------------------------------- Draw rigid elements ----------------------------------------------------------------------*/ int main() { vgl_DrawFun *df; vis_VisContext *vc; vis_ColorMap *cmap; vis_RigidElem *rigidelem; vis_EProp *eprop; GLWin *glwin; Vfloat x[4][3]; Vint dofflagind[4], dofflagdep[4]; Vfloat wgts[4]; /* create GL device */ glwin = GLWinBegin (); GLWinCreateWindow (glwin,200,200,400,400); GLWinOrtho (glwin,-2.,2.,-2.,2.,-2.,2.); /* create draw function object for GL */ df = vgl_DrawFunBegin (); GLWinDrawFun (glwin,df); vc = vis_VisContextBegin (); vis_VisContextSetColor (vc,1); vis_VisContextSetMinorColor (vc,7); vis_VisContextSetSize (vc,.5); vis_VisContextSetShade (vc,VIS_VERTEXSHADE); vis_VisContextSetRefinement (vc,2); vis_VisContextSetABCColor (vc,3,7,7); /* color map */ cmap = vis_ColorMapBegin (); vis_ColorMapSetRGB (cmap,8,0,rgb); /* create eprop object to control display */ eprop = vis_EPropBegin(); vis_EPropDef (eprop,SYS_ELEM_RIGID); /* create rigidelem object and set objects */ rigidelem = vis_RigidElemBegin (); vis_RigidElemSetObject (rigidelem,VGL_DRAWFUN,df); vis_RigidElemSetObject (rigidelem,VIS_VISCONTEXT,vc); vis_RigidElemSetObject (rigidelem,VIS_COLORMAP,cmap); vis_RigidElemSetObject (rigidelem,VIS_EPROP,eprop); vis_VisContextSetElemRep (vc,VIS_ELEMREP_SOLID); vis_RigidElemSetParami (rigidelem,RIGIDELEM_PROP,VIS_ON); x[0][0] = 0.; x[0][1] = 0.; x[0][2] = 0.; x[1][0] = 1.; x[1][1] = 1.; x[1][2] = 1.; x[2][0] = 1.; x[2][1] = .5; x[2][2] = 0.; x[3][0] = 0.; x[3][1] = 1.; x[3][2] = 1.; /* draw distributing coupling, RBE3 */ vis_VisContextSetFlags (vc,VIS_DOFBACK); vis_EPropSetValuei (eprop,EPROP_DOFFLAG_NUM,4); dofflagdep[0] = 63; dofflagdep[1] = 0; dofflagdep[2] = 0; dofflagdep[3] = 0; dofflagind[0] = 0; dofflagind[1] = 7; dofflagind[2] = 7; dofflagind[3] = 7; vis_EPropSetValueiv (eprop,EPROP_DOFFLAG_IND,dofflagind); vis_EPropSetValueiv (eprop,EPROP_DOFFLAG_DEP,dofflagdep); wgts[0] = 1.; wgts[1] = 1.; wgts[2] = .5; wgts[3] = .25; vis_RigidElemSetParami (rigidelem,RIGIDELEM_WGTSIZEFLAG,VIS_ON); vis_RigidElemSetParamf (rigidelem,RIGIDELEM_WGTSIZE,.1); vis_EPropSetValuefv (eprop,EPROP_DOFFLAG_WGTS,wgts); vis_RigidElemSetSpec (rigidelem,SYS_RIGID_DIST); /* 4 nodes; 1 dependent, 3 independent */ vis_RigidElemSetTopology (rigidelem,SYS_SHAPEPOINT,4); /* with properties */ rotate_elem (df,rigidelem,x,"Distributing Coupling with Properties"); vgl_DrawFunDelay(df,2.); /* without properties */ vis_RigidElemSetParami (rigidelem,RIGIDELEM_PROP,VIS_OFF); vis_RigidElemSetParami (rigidelem,RIGIDELEM_WGTSIZEFLAG,VIS_OFF); rotate_elem (df,rigidelem,x,"Distributing Coupling without Properties"); vgl_DrawFunDelay(df,2.); /* draw kinematic coupling, RBE2 */ vis_RigidElemSetParami (rigidelem,RIGIDELEM_PROP,VIS_ON); vis_EPropSetValuei (eprop,EPROP_DOFFLAG_NUM,2); dofflagdep[0] = 0; dofflagdep[1] = 7; dofflagind[0] = 63; dofflagind[1] = 0; vis_EPropSetValueiv (eprop,EPROP_DOFFLAG_IND,dofflagind); vis_EPropSetValueiv (eprop,EPROP_DOFFLAG_DEP,dofflagdep); vis_RigidElemSetSpec (rigidelem,SYS_RIGID_DIST); rotate_elem (df,rigidelem,x,"Kinematic Coupling"); vgl_DrawFunDelay(df,2.); /* rigid link, RROD */ vis_RigidElemSetSpec (rigidelem,SYS_RIGID_LINK); vis_EPropSetValuei (eprop,EPROP_DOFFLAG_NUM,2); dofflagdep[0] = 2; dofflagdep[1] = 0; dofflagind[0] = 5; dofflagind[1] = 7; vis_EPropSetValueiv (eprop,EPROP_DOFFLAG_IND,dofflagind); vis_EPropSetValueiv (eprop,EPROP_DOFFLAG_DEP,dofflagdep); vis_RigidElemSetTopology (rigidelem,SYS_SHAPELINE,2); rotate_elem (df,rigidelem,x,"Rigid Link"); vgl_DrawFunDelay(df,2.); /* rigid triangular plate, RTRPLT */ vis_RigidElemSetSpec (rigidelem,SYS_RIGID_KINE); vis_RigidElemSetTopology (rigidelem,SYS_SHAPETRI,2); vis_RigidElemSetParami (rigidelem,RIGIDELEM_PROP,VIS_OFF); rotate_elem (df,rigidelem,x,"Rigid Triangular Plate"); vgl_DrawFunDelay(df,2.); /* multi-point constraint */ vis_RigidElemSetSpec (rigidelem,SYS_RIGID_MPC); vis_EPropSetValuei (eprop,EPROP_DOFFLAG_NUM,4); dofflagdep[0] = 2; dofflagdep[1] = 0; dofflagdep[2] = 0; dofflagdep[3] = 0; dofflagind[0] = 0; dofflagind[1] = 2; dofflagind[2] = 4; dofflagind[3] = 2; vis_EPropSetValueiv (eprop,EPROP_DOFFLAG_IND,dofflagind); vis_EPropSetValueiv (eprop,EPROP_DOFFLAG_DEP,dofflagdep); wgts[0] = 1.; wgts[1] = .5; wgts[2] = 1.51265; wgts[3] = .5; vis_EPropSetValuefv (eprop,EPROP_DOFFLAG_WGTS,wgts); vis_RigidElemSetParami (rigidelem,RIGIDELEM_PROP,VIS_ON); vis_RigidElemSetTopology (rigidelem,SYS_SHAPEPOINT,4); rotate_elem (df,rigidelem,x,"Multi-Point Constraint"); vgl_DrawFunDelay(df,2.); /* free all objects */ vgl_DrawFunEnd (df); vis_VisContextEnd (vc); vis_ColorMapEnd (cmap); vis_RigidElemEnd (rigidelem); vis_EPropEnd (eprop); GLWinEnd (glwin); return 0; } /*---------------------------------------------------------------------- draw element ----------------------------------------------------------------------*/ void draw_elem(vgl_DrawFun *df, vis_RigidElem *rigidelem, Vfloat x[][3], Vchar *text) { vgl_DrawFunClear (df); vgl_DrawFunColor (df,ctex); vgl_DrawFunText (df,xtex,text); vis_RigidElemCurv (rigidelem,x); vgl_DrawFunSwap (df); } void rotate_elem(vgl_DrawFun *df, vis_RigidElem *rigidelem, Vfloat x[][3], Vchar *text) { Vint i; vgl_Xfm *xfm; Vfloat tm[4][4]; xfm = vgl_XfmBegin (); for(i = 0; i < 8; i++) { vgl_DrawFunClear (df); vgl_DrawFunColor (df,ctex); vgl_DrawFunText (df,xtex,text); vgl_DrawFunXfmPush (df); vgl_XfmRotate (xfm,-i*8.*3.14/180.,XFM_YAXIS); vgl_XfmGetMatrix (xfm,tm); vgl_DrawFunXfmLoad (df,tm); vis_RigidElemCurv (rigidelem,x); vgl_DrawFunSwap (df); vgl_DrawFunXfmPop (df); vgl_DrawFunDelay(df,1.); } vgl_XfmEnd (xfm); }
The first type drawn is a scalar mass (eg. NASTRAN CMASS1). The special type is set using vis_MassElemSetSpec with value SYS_MASS_SCALAR. The topology should be SYS_SHAPELINE for a node to node mass. The scalar mass connects a y translation at the first node to a z translation at the second node. The topology is then changed to SYS_SHAPEPOINT for a single node. This will draw a node to ground scalar mass.
The next type drawn is a lumped mass with rotary inertia (eg. NASTRAN CONM2). The special type is set using vis_MassElemSetSpec with value SYS_MASS_LUMP. The topology should be SYS_SHAPEPOINT. A local system is defined to orient the rotary inertia icons. The offset is drawn as a dashed line.
The final type drawn is a mass matrix (eg. NASTRAN CONM1). The special type is set using vis_MassElemSetSpec with value SYS_MASS_MATRIX. The topology should be SYS_SHAPEPOINT. A local system is defined to orient the matrix icon. The mass matrix is also drawn as a bitmap by calling vis_VisContextSetElemRep with value VIS_ELEMREP_BITMAP. The bitmap size is gradually increased.
#include "base/base.h" #include "vgl/vgl.h" #include "vis/vis.h" #include "glwin.h" static Vfloat rgb[8][3] = { {.5,.5,.5}, {1.,0.,0.}, {0.,1.,0.}, {0.,0.,1.}, {0.,1.,1.}, {1.,0.,1.}, {1.,1.,0.}, {1.,1.,1.} }; static Vfloat xtex[3] = { -1.8, 1.5, 0. }; static Vfloat ctex[3] = { 1., 1., 1. }; void draw_elem(vgl_DrawFun *df, vis_MassElem *masselem, Vfloat x[][3], Vchar *text); void rotate_elem(vgl_DrawFun *df, vis_MassElem *masselem, Vfloat x[][3], Vchar *text); /*---------------------------------------------------------------------- Draw mass elements ----------------------------------------------------------------------*/ int main() { vgl_DrawFun *df; vis_VisContext *vc; vis_ColorMap *cmap; vis_MassElem *masselem; vis_EProp *eprop; vis_CoordSys *coordsys; GLWin *glwin; Vint i; Vfloat x[2][3]; Vfloat xyzoff[3], inertia[6]; Vfloat xo[3], v1[3], v2[3], vec[3]; /* create GL device */ glwin = GLWinBegin (); GLWinCreateWindow (glwin,200,200,400,400); GLWinOrtho (glwin,-2.,2.,-2.,2.,-2.,2.); /* create drawing function object for GLWin */ df = vgl_DrawFunBegin (); GLWinDrawFun (glwin,df); vc = vis_VisContextBegin (); vis_VisContextSetColor (vc,7); vis_VisContextSetMinorColor (vc,1); vis_VisContextSetSize (vc,.5); vis_VisContextSetShade (vc,VIS_VERTEXSHADE); vis_VisContextSetRefinement (vc,2); vis_VisContextSetXYZColor (vc,4,5,6); vis_VisContextSetABCColor (vc,3,7,7); /* color map */ cmap = vis_ColorMapBegin (); vis_ColorMapSetRGB (cmap,8,0,rgb); /* create eprop object to control display */ eprop = vis_EPropBegin(); vis_EPropDef (eprop,SYS_ELEM_MASS); /* create coordsys object to define local system */ coordsys = vis_CoordSysBegin(); vis_CoordSysDef (coordsys,SYS_CARTESIAN); /* create masselem object and set objects */ masselem = vis_MassElemBegin (); vis_MassElemSetObject (masselem,VGL_DRAWFUN,df); vis_MassElemSetObject (masselem,VIS_VISCONTEXT,vc); vis_MassElemSetObject (masselem,VIS_COLORMAP,cmap); vis_MassElemSetObject (masselem,VIS_EPROP,eprop); vis_VisContextSetElemRep (vc,VIS_ELEMREP_SOLID); vis_MassElemSetParami (masselem,MASSELEM_PROP,VIS_ON); x[0][0] = 0.; x[0][1] = 0.; x[0][2] = 0.; x[1][0] = 1.; x[1][1] = 1.; x[1][2] = 1.; /* draw scalar mass */ vis_VisContextSetFlags (vc,VIS_DOFBACK); vis_EPropSetValuef (eprop,EPROP_MASS,1.); vis_EPropSetValuei (eprop,EPROP_DOF1,2); vis_EPropSetValuei (eprop,EPROP_DOF2,4); vis_MassElemSetSpec (masselem,SYS_MASS_SCALAR); vis_MassElemSetTopology (masselem,SYS_SHAPELINE,2); rotate_elem (df,masselem,x,"Node to Node Scalar Mass"); vgl_DrawFunDelay(df,2.); /* draw node to ground scalar mass */ vis_MassElemSetTopology (masselem,SYS_SHAPEPOINT,1); draw_elem (df,masselem,x,"Node to Ground Scalar Mass"); vgl_DrawFunDelay(df,2.); /* lumped mass with rotary inertia and offset */ vis_MassElemSetSpec (masselem,SYS_MASS_LUMP); vis_VisContextSetMinorLineStyle (vc,VIS_DASHDASH); /* magnitudes of mass, inertia do not affect icon size */ inertia[0] = 1.; inertia[1] = 2.; inertia[2] = 3.; inertia[3] = 1.; inertia[4] = 2.; inertia[5] = 3.; vis_EPropSetValuefv (eprop,EPROP_INERTIA,inertia); /* offset is represented physically */ xyzoff[0] = .5; xyzoff[1] = .3; xyzoff[2] = .1; vis_EPropSetValuefv (eprop,EPROP_OFFSETVEC,xyzoff); /* set and draw local system orientation */ vis_VisContextSetElemAxes (vc,VIS_ON); xo[0] = 0.; xo[1] = 0.; xo[2] = 0.; v1[0] = 1.; v1[1] = 1.; v1[2] = 0.; v2[0] = 0.; v2[1] = 1.; v2[2] = 0.; vis_CoordSysSetOriginVectors (coordsys,xo,v1,v2); vis_CoordSysRotAng (coordsys,x[0],vec); vis_MassElemSetLocalSystem (masselem,SYS_ELEMSYS_ROTANG,vec,0.); rotate_elem (df,masselem,x,"Lumped Mass with Rotary Inertia"); vgl_DrawFunDelay(df,2.); /* mass matrix */ vis_MassElemSetSpec (masselem,SYS_MASS_MATRIX); /* open box representation */ rotate_elem (df,masselem,x,"Mass Matrix"); vgl_DrawFunDelay(df,2.); /* checker box representation */ vis_MassElemSetParami (masselem,MASSELEM_CHECKER,VIS_ON); rotate_elem (df,masselem,x,"Mass Matrix"); vgl_DrawFunDelay(df,2.); /* mass matrix bitmap representation */ vis_VisContextSetElemRep (vc,VIS_ELEMREP_BITMAP); vis_MassElemSetSpec (masselem,SYS_MASS_MATRIX); for(i = 1; i < 8; i++) { vis_VisContextSetBitmapSize (vc,i); draw_elem (df,masselem,x,"Mass Matrix"); vgl_DrawFunDelay(df,1.); } vgl_DrawFunDelay(df,2.); /* free all objects */ vgl_DrawFunEnd (df); vis_VisContextEnd (vc); vis_ColorMapEnd (cmap); vis_MassElemEnd (masselem); vis_EPropEnd (eprop); vis_CoordSysEnd (coordsys); GLWinEnd (glwin); return 0; } /*---------------------------------------------------------------------- draw element ----------------------------------------------------------------------*/ void draw_elem(vgl_DrawFun *df, vis_MassElem *masselem, Vfloat x[][3], Vchar *text) { vgl_DrawFunClear (df); vgl_DrawFunColor (df,ctex); vgl_DrawFunText (df,xtex,text); vis_MassElemCurv (masselem,x); vgl_DrawFunSwap (df); } void rotate_elem(vgl_DrawFun *df, vis_MassElem *masselem, Vfloat x[][3], Vchar *text) { Vint i; vgl_Xfm *xfm; Vfloat tm[4][4]; xfm = vgl_XfmBegin (); for(i = 0; i < 8; i++) { vgl_DrawFunClear (df); vgl_DrawFunColor (df,ctex); vgl_DrawFunText (df,xtex,text); vgl_DrawFunXfmPush (df); vgl_XfmRotate (xfm,-i*8.*3.14/180.,XFM_YAXIS); vgl_XfmGetMatrix (xfm,tm); vgl_DrawFunXfmLoad (df,tm); vis_MassElemCurv (masselem,x); vgl_DrawFunSwap (df); vgl_DrawFunXfmPop (df); vgl_DrawFunDelay(df,1.); } vgl_XfmEnd (xfm); }
The first type drawn is a scalar spring (eg. NASTRAN CELAS1). The special type is set using vis_DiscElemSetSpec with value SYS_SPRINGDASHPOT_SCALAR. The topology should be SYS_SHAPELINE for a node to node spring. The element damping property is set to zero to suppress the drawing of the dashpot icon. The scalar spring connects a y translation at the first node to a z translation at the second node.
The next type drawn is a link spring and dashpot (eg. ANSYS COMBIN14). The special type is set using vis_DiscElemSetSpec with value SYS_SPRINGDASHPOT_LINK. Element properties are set for both stiffness and damping to activate drawing the spring and dashpot icons. The topology should be SYS_SHAPELINE. The topology is then changed to SYS_SHAPEPOINT for a single node. This will draw a node to ground spring and dashpot. Then the stiffness and damping properties are successively set to zero to disable the spring and then the dashpot. The representation is then set to line by calling vis_VisContextSetElemRep with value VIS_ELEMREP_LINE. Then the representation is set to bitmap and the bitmap size is gradually increased.
The next type drawn is a bush spring (eg. NASTRAN CBUSH). The special type is set using vis_DiscElemSetSpec with value SYS_SPRINGDASHPOT_BUSH. The bush spring icon displays both translational and rotational spring stiffness icons. The topology should be SYS_SHAPELINE.
The final type drawn is a weld spring (eg. NASTRAN CWELD). The special type is set using vis_DiscElemSetSpec with value SYS_SPRINGDASHPOT_WELD. The weld icon is assumed to have two physical endpoints. It is defined by a spot weld location and diameter and the nature of the connections at its two endpoints. A spot weld connection is assumed to be smeared over an adjacent element. The function vis_DiscElemSetEndTopo is used to specify the topologies of the elements connected to each endpoint. In this case a 4 node quadrilateral for the first endpoint and a 3 node triangle for the second endpoint. The endpoint locations are specified using the function vis_DiscElemSetEndCon. These endpoint locations are projected onto the elements connected to each endpoint. The topology of the element is SYS_SHAPEPOINT and maxi should be set to the total number of points in the adjacent connected elements.
#include "base/base.h" #include "vgl/vgl.h" #include "vis/vis.h" #include "glwin.h" static Vfloat rgb[8][3] = { {.5,.5,.5}, {1.,0.,0.}, {0.,1.,0.}, {0.,0.,1.}, {0.,1.,1.}, {1.,0.,1.}, {1.,1.,0.}, {1.,1.,1.} }; static Vfloat xtex[3] = { -1.8, 1.5, 0. }; static Vfloat ctex[3] = { 1., 1., 1. }; void draw_elem(vgl_DrawFun *df, vis_DiscElem *discelem, Vfloat x[][3], Vchar *text); void rotate_elem(vgl_DrawFun *df, vis_DiscElem *discelem, Vfloat x[][3], Vchar *text); /*---------------------------------------------------------------------- Draw discrete elements ----------------------------------------------------------------------*/ int main() { vgl_DrawFun *df; vis_VisContext *vc; vis_ColorMap *cmap; vis_DiscElem *discelem; vis_EProp *eprop; GLWin *glwin; int i; Vfloat x[7][3]; Vfloat xend[3]; /* create GL device */ glwin = GLWinBegin (); GLWinCreateWindow (glwin,200,200,400,400); GLWinOrtho (glwin,-2.,2.,-2.,2.,-2.,2.); /* create draw function object for GL */ df = vgl_DrawFunBegin (); GLWinDrawFun (glwin,df); vc = vis_VisContextBegin (); vis_VisContextSetColor (vc,1); vis_VisContextSetMinorColor (vc,7); vis_VisContextSetSize (vc,.5); vis_VisContextSetShade (vc,VIS_VERTEXSHADE); vis_VisContextSetRefinement (vc,2); vis_VisContextSetABCColor (vc,3,7,7); /* color map */ cmap = vis_ColorMapBegin (); vis_ColorMapSetRGB (cmap,8,0,rgb); /* create eprop object to control display */ eprop = vis_EPropBegin(); vis_EPropDef (eprop,SYS_ELEM_SPRINGDASHPOT); /* create discelem object and set objects */ discelem = vis_DiscElemBegin (); vis_DiscElemSetObject (discelem,VGL_DRAWFUN,df); vis_DiscElemSetObject (discelem,VIS_VISCONTEXT,vc); vis_DiscElemSetObject (discelem,VIS_COLORMAP,cmap); vis_DiscElemSetObject (discelem,VIS_EPROP,eprop); vis_VisContextSetElemRep (vc,VIS_ELEMREP_SOLID); vis_DiscElemSetParami (discelem,DISCELEM_WINDINGS,2); vis_DiscElemSetParami (discelem,DISCELEM_PROP,VIS_ON); x[0][0] = 0.; x[0][1] = 0.; x[0][2] = 0.; x[1][0] = 1.; x[1][1] = 1.; x[1][2] = 1.; /* draw scalar spring */ vis_VisContextSetFlags (vc,VIS_DOFBACK); vis_EPropSetValuei (eprop,EPROP_DOF1,2); vis_EPropSetValuei (eprop,EPROP_DOF2,4); vis_EPropSetValuef (eprop,EPROP_STIFF,1.); vis_EPropSetValuef (eprop,EPROP_DAMP,0.); vis_DiscElemSetSpec (discelem,SYS_SPRINGDASHPOT_SCALAR); vis_DiscElemSetTopology (discelem,SYS_SHAPELINE,2); rotate_elem (df,discelem,x,"Node to Node Scalar Spring"); vgl_DrawFunDelay(df,2.); /* draw link spring and dashpot */ vis_EPropSetValuef (eprop,EPROP_STIFF,1.); vis_EPropSetValuef (eprop,EPROP_DAMP,1.); vis_DiscElemSetSpec (discelem,SYS_SPRINGDASHPOT_LINK); vis_DiscElemSetTopology (discelem,SYS_SHAPELINE,2); rotate_elem (df,discelem,x,"Node to Node Link Spring and Dashpot"); vgl_DrawFunDelay(df,2.); /* draw node to ground spring and dashpot */ vis_DiscElemSetTopology (discelem,SYS_SHAPEPOINT,1); draw_elem (df,discelem,x,"Node to Ground Spring and Dashpot"); vgl_DrawFunDelay(df,2.); /* draw node to ground dashpot only */ vis_EPropSetValuef (eprop,EPROP_STIFF,0.); draw_elem (df,discelem,x,"Node to Ground Link Dashpot"); vgl_DrawFunDelay(df,2.); /* draw node to ground spring only */ vis_EPropSetValuef (eprop,EPROP_STIFF,1.); vis_EPropSetValuef (eprop,EPROP_DAMP,0.); draw_elem (df,discelem,x,"Node to Ground Link Spring"); vgl_DrawFunDelay(df,2.); /* draw node to ground spring only, line representation */ vis_VisContextSetElemRep (vc,VIS_ELEMREP_LINE); draw_elem (df,discelem,x,"Node to Ground Link Spring"); vgl_DrawFunDelay(df,2.); /* draw node to ground spring only, bitmap representation */ vis_VisContextSetElemRep (vc,VIS_ELEMREP_BITMAP); for(i = 1; i < 8; i++) { vis_VisContextSetBitmapSize (vc,i); draw_elem (df,discelem,x,"Node to Ground Link Spring"); vgl_DrawFunDelay(df,1.); } vgl_DrawFunDelay(df,2.); vis_VisContextSetBitmapSize (vc,1); /* draw bush with translation and rotation springs */ vis_VisContextSetElemRep (vc,VIS_ELEMREP_SOLID); vis_EPropSetValuef (eprop,EPROP_STIFFTRA,1.); vis_EPropSetValuef (eprop,EPROP_STIFFROT,1.); vis_DiscElemSetSpec (discelem,SYS_SPRINGDASHPOT_BUSH); vis_DiscElemSetTopology (discelem,SYS_SHAPELINE,2); rotate_elem (df,discelem,x,"Node to Node Bush"); vgl_DrawFunDelay(df,2.); /* draw weld with topological end connections */ /* end A quad */ x[0][0] = 0.; x[0][1] = 0.; x[0][2] = 0.; x[1][0] = 1.; x[1][1] = 0.; x[1][2] = 0.; x[2][0] = 1.; x[2][1] = 1.; x[2][2] = 0.; x[3][0] = 0.; x[3][1] = 1.; x[3][2] = 0.; /* end B tri */ x[4][0] = 0.; x[4][1] = 0.; x[4][2] = 1.; x[5][0] = 1.; x[5][1] = 0.; x[5][2] = 1.; x[6][0] = 1.; x[6][1] = 1.; x[6][2] = 1.; /* set diameter of weld */ vis_EPropSetValuef (eprop,EPROP_DOUT,.2); vis_DiscElemSetSpec (discelem,SYS_SPRINGDASHPOT_WELD); /* set topologies of end points */ vis_DiscElemSetEndTopo (discelem,SYS_TOPO_QUAD4SER,SYS_TOPO_TRI3); /* location of spot weld */ xend[0] = .4; xend[1] = .2; xend[2] = .5; vis_DiscElemSetEndCon (discelem,SYS_ELEMEND_POSITION,xend, SYS_ELEMEND_POSITION,xend); vis_DiscElemSetTopology (discelem,SYS_SHAPEPOINT,7); rotate_elem (df,discelem,x,"Elem to Elem Weld"); vgl_DrawFunDelay(df,2.); /* free all objects */ vgl_DrawFunEnd (df); vis_VisContextEnd (vc); vis_ColorMapEnd (cmap); vis_DiscElemEnd (discelem); vis_EPropEnd (eprop); GLWinEnd (glwin); return 0; } /*---------------------------------------------------------------------- draw element ----------------------------------------------------------------------*/ void draw_elem(vgl_DrawFun *df, vis_DiscElem *discelem, Vfloat x[][3], Vchar *text) { vgl_DrawFunClear (df); vgl_DrawFunColor (df,ctex); vgl_DrawFunText (df,xtex,text); vis_DiscElemCurv (discelem,x); vgl_DrawFunSwap (df); } void rotate_elem(vgl_DrawFun *df, vis_DiscElem *discelem, Vfloat x[][3], Vchar *text) { Vint i; vgl_Xfm *xfm; Vfloat tm[4][4]; xfm = vgl_XfmBegin (); for(i = 0; i < 8; i++) { vgl_DrawFunClear (df); vgl_DrawFunColor (df,ctex); vgl_DrawFunText (df,xtex,text); vgl_DrawFunXfmPush (df); vgl_XfmRotate (xfm,-i*8.*3.14/180.,XFM_YAXIS); vgl_XfmGetMatrix (xfm,tm); vgl_DrawFunXfmLoad (df,tm); vis_DiscElemCurv (discelem,x); vgl_DrawFunSwap (df); vgl_DrawFunXfmPop (df); vgl_DrawFunDelay(df,1.); } vgl_XfmEnd (xfm); }
The first type drawn is a node to node gap (eg. NASTRAN CGAP). The topology should be SYS_SHAPELINE. The gap element initial gap is set to .05. The node points are non coincident so that the gap local coordinate system, by default, will be constructed with the x' direction oriented from the first to the second node. The initial gap will be accurately represented in the distance between the gap icons. Then the gap is drawn again with the two coincident nodes. In this case no x' axis can be computed and an explicit element system should be specified using vis_GapElemSetLocalSystem. The local system is displayed by enabling vis_VisContextSetElemAxes.
Finally the topology is set to a single point, the detailed element properties are disabled and a grounded gap is drawn.
#include "base/base.h" #include "vgl/vgl.h" #include "vis/vis.h" #include "glwin.h" static Vfloat rgb[8][3] = { {.5,.5,.5}, {1.,0.,0.}, {0.,1.,0.}, {0.,0.,1.}, {0.,1.,1.}, {1.,0.,1.}, {1.,1.,0.}, {1.,1.,1.} }; static Vfloat xtex[3] = { -1.8, 1.5, 0. }; static Vfloat ctex[3] = { 1., 1., 1. }; void draw_elem(vgl_DrawFun *df, vis_GapElem *gapelem, Vfloat x[][3], Vchar *text); void rotate_elem(vgl_DrawFun *df, vis_GapElem *gapelem, Vfloat x[][3], Vchar *text); /*---------------------------------------------------------------------- Draw gap elements ----------------------------------------------------------------------*/ int main() { vgl_DrawFun *df; vis_VisContext *vc; vis_ColorMap *cmap; vis_GapElem *gapelem; vis_EProp *eprop; vis_CoordSys *coordsys; GLWin *glwin; Vfloat x[2][3]; Vfloat xo[3], v1[3], v2[3], vec[3]; /* create GL device */ glwin = GLWinBegin (); GLWinCreateWindow (glwin,200,200,400,400); GLWinOrtho (glwin,-2.,2.,-2.,2.,-2.,2.); /* create draw function object for GL */ df = vgl_DrawFunBegin (); GLWinDrawFun (glwin,df); vc = vis_VisContextBegin (); vis_VisContextSetColor (vc,1); vis_VisContextSetMinorColor (vc,7); vis_VisContextSetSize (vc,.5); vis_VisContextSetShade (vc,VIS_VERTEXSHADE); vis_VisContextSetRefinement (vc,2); vis_VisContextSetABCColor (vc,3,7,7); vis_VisContextSetXYZColor (vc,4,5,6); /* color map */ cmap = vis_ColorMapBegin (); vis_ColorMapSetRGB (cmap,8,0,rgb); /* create eprop object to control display */ eprop = vis_EPropBegin(); vis_EPropDef (eprop,SYS_ELEM_GAP); /* create coordsys object to define local system */ coordsys = vis_CoordSysBegin(); vis_CoordSysDef (coordsys,SYS_CARTESIAN); /* create gapelem object and set objects */ gapelem = vis_GapElemBegin (); vis_GapElemSetObject (gapelem,VGL_DRAWFUN,df); vis_GapElemSetObject (gapelem,VIS_VISCONTEXT,vc); vis_GapElemSetObject (gapelem,VIS_COLORMAP,cmap); vis_GapElemSetObject (gapelem,VIS_EPROP,eprop); vis_VisContextSetElemRep (vc,VIS_ELEMREP_SOLID); vis_GapElemSetParami (gapelem,DISCELEM_PROP,VIS_ON); x[0][0] = 0.; x[0][1] = 0.; x[0][2] = 0.; x[1][0] = 1.; x[1][1] = 0.; x[1][2] = 0.; /* draw node to node gap */ vis_GapElemSetTopology (gapelem,SYS_SHAPELINE,2); vis_EPropSetValuef (eprop,EPROP_UZERO,.05); /* non coincident nodes */ rotate_elem (df,gapelem,x,"Node to Node Gap Non Coincident"); vgl_DrawFunDelay(df,2.); /* coincident nodes, need local system for orientation */ x[1][0] = 0.; x[1][1] = 0.; x[1][2] = 0.; vis_VisContextSetElemAxes (vc,VIS_ON); xo[0] = 0.; xo[1] = 0.; xo[2] = 0.; v1[0] = 1.; v1[1] = 1.; v1[2] = 0.; v2[0] = 0.; v2[1] = 1.; v2[2] = 0.; vis_CoordSysSetOriginVectors (coordsys,xo,v1,v2); vis_CoordSysRotAng (coordsys,x[0],vec); vis_GapElemSetLocalSystem (gapelem,SYS_ELEMSYS_ROTANG,vec,0.); rotate_elem (df,gapelem,x,"Node to Node Gap Coincident"); vgl_DrawFunDelay(df,2.); /* draw node to ground gap */ vis_GapElemSetParami (gapelem,DISCELEM_PROP,VIS_OFF); vis_GapElemSetTopology (gapelem,SYS_SHAPEPOINT,1); rotate_elem (df,gapelem,x,"Node to Ground Gap"); vgl_DrawFunDelay(df,2.); /* free all objects */ vgl_DrawFunEnd (df); vis_VisContextEnd (vc); vis_ColorMapEnd (cmap); vis_GapElemEnd (gapelem); vis_EPropEnd (eprop); vis_CoordSysEnd (coordsys); GLWinEnd (glwin); return 0; } /*---------------------------------------------------------------------- draw element ----------------------------------------------------------------------*/ void draw_elem(vgl_DrawFun *df, vis_GapElem *gapelem, Vfloat x[][3], Vchar *text) { vgl_DrawFunClear (df); vgl_DrawFunColor (df,ctex); vgl_DrawFunText (df,xtex,text); vis_GapElemCurv (gapelem,x); vgl_DrawFunSwap (df); } void rotate_elem(vgl_DrawFun *df, vis_GapElem *gapelem, Vfloat x[][3], Vchar *text) { Vint i; vgl_Xfm *xfm; Vfloat tm[4][4]; xfm = vgl_XfmBegin (); for(i = 0; i < 8; i++) { vgl_DrawFunClear (df); vgl_DrawFunColor (df,ctex); vgl_DrawFunText (df,xtex,text); vgl_DrawFunXfmPush (df); vgl_XfmRotate (xfm,-i*8.*3.14/180.,XFM_YAXIS); vgl_XfmGetMatrix (xfm,tm); vgl_DrawFunXfmLoad (df,tm); vis_GapElemCurv (gapelem,x); vgl_DrawFunSwap (df); vgl_DrawFunXfmPop (df); vgl_DrawFunDelay(df,1.); } vgl_XfmEnd (xfm); }
#include "base/base.h" #include "vis/vis.h" #include "vgl/vgl.h" static Vfloat rgb[7][3] = { {.2,.2,.2}, {1.,0.,0.}, {0.,1.,0.}, {0.,0.,1.}, {0.,1.,1.}, {1.,0.,1.}, {1.,1.,0.} }; #define NPOINTS 13 #define NLINES 12 static Vfloat pts[NPOINTS][3] = { {-0.4,-0.5,0.}, { 0.4,-0.5,0.}, { 0.4, 0.0,0.}, {-0.4, 0.0,0.}, {-0.8, 0.0,0.}, { 0.8, 0.0,0.}, { 0.8, 0.8,0.}, {-0.8, 0.8,0.}, { 0.0, 0.5,0.}, {-0.2, 0.2,0.}, {-0.2, 0.4,0.}, { 0.2, 0.4,0.}, { 0.2, 0.2,0.} }; static Vint lines[NLINES][3] = { /* bottom polygon */ {1,2,0}, {2,3,0}, {3,4,0}, {4,1,0}, /* top polygon */ {5,6,0}, {6,7,0}, {7,9,8}, /* this is an arc */ {8,5,0}, /* hole in top polygon */ {10,11,0}, {11,12,0}, {12,13,0}, {13,10,0} }; /* text drawing */ static Vfloat xtxt[3] = {-0.8,0.9,0.}; static Vfloat white[3] = {1.,1.,1.}; /* device pixel sizes */ static Vint isize[3] = {5, 10, 50}; /*---------------------------------------------------------------------- Draw a 2D Polygon ----------------------------------------------------------------------*/ int main() { #ifdef VKI_WIND_X11 Display *display; int screen; #endif vis_Tess *tess; vis_VisContext *vc; vis_ColorMap *cm; vgl_DrawFun *df; vgl_OpenGLDev *ogldev; Vint n; Vint devicesize; Vint parami[4]; Vchar buffer[80]; Vfloat paramf[16]; #ifdef VKI_WIND_X11 /* open X display */ display = XOpenDisplay (0); screen = DefaultScreen (display); vgl_OpenGLDevConnectX (display,screen); #endif #ifdef VKI_WIND_WIN32 vgl_OpenGLDevConnectWIN (); #endif /* create GL device */ ogldev = vgl_OpenGLDevBegin (); /* create drawing functions */ df = vgl_DrawFunBegin(); vgl_OpenGLDevDrawFun (ogldev,df); vgl_DrawFunPositionWindow (df,100,400,400,400); vgl_DrawFunOpenWindow (df,"Example 19 vgl"); vgl_DrawFunProjOrtho (df,-1.,1.,-1.,1.,-1.,1.); /* vis context and set attributes */ vc = vis_VisContextBegin (); vis_VisContextSetColor (vc,3); vis_VisContextSetMinorColor (vc,5); vis_VisContextSetLineWidth (vc,2); vis_VisContextSetLineStyle (vc,VGL_LINESTYLE_DASH); vis_VisContextSetFill (vc,1); vis_VisContextSetEdge (vc,1); vis_VisContextSetPrimType (vc,VIS_PRIM_STRIP); /* color map */ cm = vis_ColorMapBegin (); vis_ColorMapSetType (cm,COLORMAP_TRUECOLOR); vis_ColorMapSetRGB (cm,7,0,rgb); /* tess object setup */ tess = vis_TessBegin (); vis_TessSetObject (tess,VIS_VISCONTEXT,vc); vis_TessSetObject (tess,VIS_COLORMAP,cm); vis_TessSetObject (tess,VGL_DRAWFUN,df); vis_TessSetParami (tess,TESS_EDGE,TESS_EDGE_OUTLINE); vis_TessDef (tess,NPOINTS,NLINES); for(n = 1; n <= NPOINTS; n++) { vis_TessSetPoint (tess,n,pts[n-1]); } for(n = 1; n <= NLINES; n++) { if(lines[n-1][2] == 0) { vis_TessSetLine (tess,n,lines[n-1]); } else { vis_TessSetArc (tess,n,lines[n-1]); } } /* illustrate world sizing and 3 device sizes */ for(n = 1; n <= 4; n++) { vgl_DrawFunClear (df); vgl_DrawFunColor (df,white); /* world sizing */ if(n == 1) { vgl_DrawFunText (df,xtxt,"World size= 0.1"); vis_VisContextSetSizeType (vc,VIS_SIZEWORLD); vis_VisContextSetSize (vc,0.1); /* 3 device sizes, 5, 10 and 50 pixels */ /* note that Size scales DeviceSize */ } else { devicesize = isize[n-2]; sprintf(buffer,"Device size= %d",devicesize); vgl_DrawFunText (df,xtxt,buffer); vis_VisContextSetSizeType (vc,VIS_SIZEDEVICE); vis_VisContextSetSize (vc,1.); vis_VisContextSetDeviceSize (vc,devicesize); vgl_DrawFunGetFloat (df,VGL_PROJECTIONMATRIX,paramf); vis_VisContextSetProjMatrix (vc,(Vfloat(*)[4])paramf); vgl_DrawFunGetFloat (df,VGL_MODELVIEWMATRIX,paramf); vis_VisContextSetXfmMatrix (vc,(Vfloat(*)[4])paramf); vgl_DrawFunGetInteger (df,VGL_VIEWPORT,parami); vis_VisContextSetViewport (vc,parami[0],parami[1],parami[2],parami[3]); } vis_TessDraw (tess); vgl_DrawFunSwap (df); vgl_DrawFunDelay (df,5.); } /* close windows */ vgl_DrawFunCloseWindow (df); /* free objects */ vis_TessEnd (tess); vis_ColorMapEnd (cm); vis_VisContextEnd (vc); vgl_DrawFunEnd (df); vgl_OpenGLDevEnd (ogldev); /* close X display */ #ifdef VKI_WIND_X11 XCloseDisplay (display); #endif return 0; }
The function outlinesurface loops through all triangles and extracts a line which is the intersection of the cutting plane with the triangle. A possible performance optimization would be to select only those triangles which lie on the cutting plane using a geometric search tree. The line end points and line connectivity are entered into a Connect object for convenience. The line connectivity is oriented so that the cross product of the direction of the line with the normal to the cutting plane points out of the body of the geometry.
The intersection lines and points are passed to the Tess object for tesselation. The Tess object will merge all coincident points.
#include <stdio.h> #include "base/base.h" #include "vgl/vgl.h" #include "vis/vis.h" #include "vis/exam/glwin.h" static Vfloat rgb[7][3] = { {.2,.2,.2}, {1.,0.,0.}, {0.,1.,0.}, {0.,0.,1.}, {0.,1.,1.}, {1.,0.,1.}, {1.,1.,0.} }; /* a simple hollow cube */ static Vdouble coords[16][3] = { {-10.,-10.,-10.}, { 10.,-10.,-10.}, {-10., 10.,-10.}, { 10., 10.,-10.}, {-10.,-10., 10.}, { 10.,-10., 10.}, {-10., 10., 10.}, { 10., 10., 10.}, {-11.,-11.,-11.}, { 11.,-11.,-11.}, {-11., 11.,-11.}, { 11., 11.,-11.}, {-11.,-11., 11.}, { 11.,-11., 11.}, {-11., 11., 11.}, { 11., 11., 11.} }; static Vint tris[24][3] = { { 3, 5, 1}, { 7, 5, 3}, { 2, 6, 4}, { 4, 6, 8}, { 5, 2, 1}, { 6, 2, 5}, { 3, 4, 7}, { 7, 4, 8}, { 2, 4, 1}, { 3, 1, 4}, { 7, 8, 5}, { 8, 6, 5}, { 9,13,11}, {11,13,15}, {12,14,10}, {16,14,12}, { 9,10,13}, {13,10,14}, {15,12,11}, {16,12,15}, { 9,12,10}, {12, 9,11}, {13,16,15}, {13,14,16} }; void loadsurface(vis_Connect *connectsrf); void readsurface(vis_Connect *connectsrf, Vchar *path); void outlinesurface(vis_Connect *connectsrf, Vdouble xn[3], Vdouble vn[3], vis_Tess *tess); /*---------------------------------------------------------------------- Cross product between two vectors ----------------------------------------------------------------------*/ static void cross(Vdouble a[3], Vdouble b[3], Vdouble c[3]) { c[0] = a[1]*b[2]-a[2]*b[1]; c[1] = a[2]*b[0]-a[0]*b[2]; c[2] = a[0]*b[1]-a[1]*b[0]; } /*---------------------------------------------------------------------- Difference between two vectors ----------------------------------------------------------------------*/ static void diff(Vdouble a[3], Vdouble b[3], Vdouble c[3]) { c[0] = a[0]-b[0]; c[1] = a[1]-b[1]; c[2] = a[2]-b[2]; } /*---------------------------------------------------------------------- Triangulate a Planar Slice of a Bounded Tesselation ----------------------------------------------------------------------*/ int main(int argc, char **argv) { vis_Connect *connectsrf; vis_Tess *tess; vis_VisContext *vc; vis_ColorMap *cmap; GLWin *glwin; vgl_DrawFun *df; Vdouble bbox[2][3], d[3], blen, xn[3], vn[3]; Vfloat xmin,xmax,ymin,ymax,zmin,zmax; Vfloat dx, dy, xc, yc, sca; Vint numunrec, numdrawtri; /* create connect object of surface */ connectsrf = vis_ConnectBegin (); /* load surface from static arrays */ if(argc < 2) { loadsurface (connectsrf); /* read surface from STL file */ } else { readsurface (connectsrf,argv[1]); } /* compute extent */ vis_ConnectExtentdv (connectsrf,NULL,bbox); diff(bbox[1],bbox[0],d); blen = sqrt(d[0]*d[0] + d[1]*d[1] + d[2]*d[2]); /* cutting plane normal to z axis */ xn[0] = 0.; xn[1] = 0.; xn[2] = .5*(bbox[0][2] + bbox[1][2]); vn[0] = 0.; vn[1] = 0.; vn[2] = 1.; xmin = bbox[0][0]; xmax = bbox[1][0]; ymin = bbox[0][1]; ymax = bbox[1][1]; zmin = bbox[0][2]; zmax = bbox[1][2]; /* determine orthographic limits to fit view */ /* assuming a square viewport */ dx = xmax-xmin; xc = .5*(xmax+xmin); dy = ymax-ymin; yc = .5*(ymax+ymin); if(dx > dy) { sca = dx/dy; ymin = yc-.5*sca*dy; ymax = yc+.5*sca*dy; } else { sca = dy/dx; xmin = xc-.5*sca*dx; xmax = xc+.5*sca*dx; } /* add a bit of margin */ xmin = xmin - .05*(xmax-xmin); xmax = xmax + .05*(xmax-xmin); ymin = ymin - .05*(ymax-ymin); ymax = ymax + .05*(ymax-ymin); /* create GL device */ glwin = GLWinBegin (); GLWinCreateWindow (glwin,200,200,400,400); /* create draw function object for GL */ df = vgl_DrawFunBegin (); GLWinDrawFun (glwin,df); GLWinOrtho (glwin,xmin,xmax,ymin,ymax,-10000.,10000); tess = vis_TessBegin (); vis_TessDef (tess,0,0); /* create outline mesh on surface triangles */ /* create tess object */ outlinesurface (connectsrf,xn,vn,tess); /* visualization context */ vc = vis_VisContextBegin (); vis_VisContextSetColor (vc,4); vis_VisContextSetMinorColor (vc,5); vis_VisContextSetShade (vc,VIS_VERTEXSHADE); vis_VisContextSetPrimType (vc,VIS_PRIM_STRIP); vis_VisContextSetEdge (vc,VIS_ON); /* color map */ cmap = vis_ColorMapBegin (); vis_ColorMapSetType (cmap,COLORMAP_TRUECOLOR); vis_ColorMapSetRGB (cmap,7,0,rgb); /* normal to cutting plane */ vis_TessSetNormaldv (tess,vn); /* set objects for drawing */ vis_TessSetObject (tess,VIS_VISCONTEXT,vc); vis_TessSetObject (tess,VIS_COLORMAP,cmap); vis_TessSetObject (tess,VGL_DRAWFUN,df); vis_TessSetParamd (tess,TESS_INTERTOL,.00001*blen); /* draw */ GLWinClear (glwin); vis_TessDraw (tess); vis_TessGetInteger (tess,TESS_NUMUNREC,&numunrec); vis_TessGetInteger (tess,TESS_NUMDRAWTRI,&numdrawtri); if(numunrec || numdrawtri == 0) { printf("numunrec= %d\n",numunrec); printf("numdrawtri= %d\n",numdrawtri); } GLWinSwap (glwin); sleep(10); /* end Tess */ vis_ConnectEnd (connectsrf); vis_TessEnd (tess); vis_ColorMapEnd (cmap); vis_VisContextEnd (vc); GLWinEnd (glwin); vgl_DrawFunEnd (df); return 0; } void loadsurface(vis_Connect *connectsrf) { Vint i; printf("load surface from static arrays\n"); vis_ConnectDef (connectsrf,0,0); /* set nodes */ for(i = 0; i < 16; i++) { vis_ConnectSetCoordsdv (connectsrf,i+1,coords[i]); } /* set triangles */ for(i = 0; i < 24; i++) { vis_ConnectSetTopology (connectsrf,i+1,VIS_SHAPETRI,2,0,0); vis_ConnectSetElemNode (connectsrf,i+1,tris[i]); } } void readsurface(vis_Connect *connectsrf, Vchar *path) { vis_Connect *connect; connect = vis_ConnectBegin(); if(strstr(path,".stl") != NULL) { printf("read surface from stl file: %s\n",path); vis_ConnectRead (connect,SYS_FILE_STL,path); } else if(strstr(path,".STL") != NULL) { printf("read surface from binary stl file: %s\n",path); vis_ConnectRead (connect,SYS_FILE_STLBIN,path); } /* copy it */ vis_ConnectCopy (connectsrf,connect); vis_ConnectEnd (connect); } void outlinesurface(vis_Connect *connectsrf, Vdouble xn[3], Vdouble vn[3], vis_Tess *tess) { Vint k, m; Vdouble x[3][3]; Vint ntris; Vint nplus, nminus; Vint np, lp[2], lix[2], npnts, nlins; Vint nix, ix[3]; Vdouble d[3], dt[3], dx[3]; Vint s[3]; Vdouble xl[2][3], xd[3], xc[3], dot, f; Vdouble vt[3][3]; vis_ConnectNumber (connectsrf,SYS_ELEM,&ntris); npnts = 0; nlins = 0; /* determine intersection line of plane and triangle */ for(m = 1; m <= ntris; m++) { vis_ConnectElemNode (connectsrf,m,&nix,ix); vis_ConnectCoordsdv (connectsrf,nix,ix,x); nplus = nminus = 0; for(k = 0; k < 3; k++) { diff(x[k],xn,d); dt[k] = vn[0]*d[0] + vn[1]*d[1] + vn[2]*d[2]; if(dt[k] >= 0.) { s[k] = 1; nplus += 1; } else if(dt[k] < 0.) { s[k] = -1; nminus += 1; } } if(nplus == 0 || nminus == 0) continue; /* compute exact intersection points */ np = 0; for(k = 0; k < 3; k++) { if(s[k] == 0) continue; if(s[(k+1)%3]*s[k] == 1) continue; diff(x[(k+1)%3],x[k],dx); f = dt[k]/(dt[k]-dt[(k+1)%3]); xl[np][0] = x[k][0] + f*dx[0]; xl[np][1] = x[k][1] + f*dx[1]; xl[np][2] = x[k][2] + f*dx[2]; lp[np] = ++npnts; vis_TessSetPointdv (tess,lp[np],xl[np]); np += 1; } vis_ConnectElemNormdv (connectsrf,m,1,vt); diff(xl[1],xl[0],xd); cross(xd,vn,xc); dot = xc[0]*vt[0][0] + xc[1]*vt[0][1] + xc[2]*vt[0][2]; if(dot >= 0.) { lix[0] = lp[0]; lix[1] = lp[1]; } else { lix[1] = lp[0]; lix[0] = lp[1]; } nlins += 1; vis_TessSetLine (tess,nlins,lix); } }