Commit ed5596e4 authored by Edward Vigmond's avatar Edward Vigmond
Browse files

Added auxiliary grids. See the manual.

parent beca3e28
#include "AuxGrid.h"
char *get_line(gzFile);
int get_num( gzFile in )
{
int number;
if( !sscanf( get_line(in), "%d", &number ) )
throw 1;
return number;
}
/* constructor
*
* \param fn base file name
* \param fn base file name
* \param pt_offset center of model coordinates
*
* \throw 1 if any error in input
*/
Auxgrid::AuxGrid:_num_tm_grid(1),_num_tm_data(0)( char *fn )
AuxGrid::AuxGrid( char *fn, const GLfloat* pt_offset ):_num_tm_grid(1),
_num_tm_data(0),_data(NULL),_display(true)
{
gzFile ptin;
char *ext = strstr( fn, ".pts_t" );
if( ext ) *ext = '\0';
gzFile pt_in;
try {
ptin = openFile( fn, ".pts_t" );
pt_in = openFile( fn, ".pts_t" );
}catch(...) {throw 1;}
_num_tm_grid = get_num( ptin );
_num_tm_grid = get_num( pt_in );
gzFile elem_in;
try {
elem_in = openFile( fn, ".elem_t" );
} catch(...) {elem_in=NULL;}
try {
data_in = openFile( fn, ".data_t" );
gzFile data_in;
try {
data_in = openFile( fn, ".dat_t" );
} catch(...) {data_in=NULL;}
//sanity checks
if( elem_in && get_num( elem_in ) != _num_tm_grid ) {
cerr << "points and element file times do not match" << endl;
cerr << "number of vertex and element time instances do not match" << endl;
throw 1;
}
if( data_in ) {
_num_tm_data = get_num( data_in );
if( _num_tm_grid>1 && _num_tm_data>1 && _num_tm_grid!=_num_tm_data ) {
cerr << "points and data file times do not match" << endl;
if( _num_tm_grid>1 && _num_tm_grid!=_num_tm_data ) {
cerr << "number of vertex and data time instances do not match" << endl;
throw 1;
}
}
_num_mod = _num_tm_grid>_num_tm_data?_num_tm_grid:_num_tm_data;
for( int i=0; i<_num_mod; i++ ) {
_model.push_back(new Model() );
read_pts_instance( pts_in );
read_elem_instance( elem_in );
read_data_instance( data_in );
_data = new DATA_TYPE*[_num_tm_data];
// read in first time step
_model.push_back(new Model());
_model.back()->read_instance( pt_in, elem_in, pt_offset );
if( data_in )
read_data_instance( data_in, _model.back()->number(Vertex), _data[0] );
for( int i=1; i<_num_mod; i++ ) {
if( _num_tm_grid>1 ) {
_model.push_back(new Model());
_model.back()->read_instance( pt_in, elem_in, pt_offset );
_model.back()->_cnnx->size(100);
_model.back()->_cnnx->threeD(true);
}
if( _num_tm_data>1 )
read_data_instance( data_in, _model.back()->number(Vertex), _data[i] );
}
for( int i=0; i<maxobject; i++ )
_show[i] = true;
}
......@@ -52,5 +85,157 @@ Auxgrid::AuxGrid:_num_tm_grid(1),_num_tm_data(0)( char *fn )
void
AuxGrid :: draw( int t )
{
if( !_display || t<0 || t>=_num_mod ) return;
Model *m = _model[_num_tm_grid==1 ? 0 : t ];
if( _autocol ) {
optimize_cs(t);
//auxmincolval->value(cs.min());
//auxmaxcolval->value(cs.max());
}
if( _show[Vertex] ) {
GLfloat r[]={0,1,0,1};
m->pt.draw( 0, m->pt.num()-1, m->get_color(Vertex),
&cs, (_data&&_datafied[Vertex])?_data[t]:NULL, 1, NULL );
}
if( _show[Cnnx] ) {
m->_cnnx->draw( 0, m->_cnnx->num()-1, m->get_color(Cnnx),
&cs, (_data&&_datafied[Cnnx])?_data[t]:NULL, 1, NULL );
}
if( _show[SurfEle] ) {
glPushAttrib(GL_POLYGON_BIT);
if( _surf_fill ) {
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
} else {
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
glLineWidth(m->size(SurfEle,0));
}
GLfloat r[]={0,1,1,1};
m->surface(0)->draw( m->get_color(SurfEle), &cs,
(_data&&_datafied[SurfEle])?_data[t]:NULL, 1, NULL,
m->vertex_normals(m->surface(0)) );
glPopAttrib();
}
if( _show[VolEle] ) {
glPushAttrib(GL_POLYGON_BIT);
if( _vol_fill ) {
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
} else {
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
glLineWidth(m->size(VolEle,0));
}
for( int i=0; i<m->number(VolEle); i++ )
m->_vol[i]->draw( 0, m->_cnnx->num()-1, m->get_color(VolEle),
&cs, (_data&&_datafied[VolEle])?_data[t]:NULL, 1, NULL );
}
glPopAttrib();
}
/** read in data for one time instance
*
* \param in input file
* \param npt number of expected data points for instance
* \param data where to store data
*
* \throw 1 input error
* \post data will be allocated
*/
void
AuxGrid::read_data_instance( gzFile in, int npt, DATA_TYPE*& data )
{
int n;
sscanf( get_line(in), "%d", &n );
if( n!=npt )
throw 1;
data = new DATA_TYPE[n];
for( int i=0; i<n; i++ ) {
if( !sscanf(get_line( in ), "%f", data+i ) )
throw 1;
}
}
/** destructor */
AuxGrid::~AuxGrid()
{
for( int i=0; i<_model.size(); i++ ) {
delete _model[i];
delete[] _data[i];
}
_model.clear();
delete[] _data;
}
/** set the size of objects */
void
AuxGrid::size( Object_t o, float s )
{
for( int i=0; i<_model.size(); i++ ) {
switch(o) {
case Vertex:
_model[i]->pt.size(s);
break;
case Cnnx:
_model[i]->_cnnx->size(s);
break;
case SurfEle:
case VolEle:
break;
}
_model[i]->size(o,-1,s);
}
}
/** set the 3Dedness of objects */
void
AuxGrid::threeD( Object_t o, bool s )
{
for( int i=0; i<_model.size(); i++ ){
switch(o) {
case Vertex:
_model[i]->pt.threeD(s);
break;
case Cnnx:
_model[i]->_cnnx->threeD(s);
break;
case SurfEle:
case VolEle:
break;
}
_model[i]->threeD(o,-1,s);
}
}
/** set the colour of objects */
void
AuxGrid::color( Object_t o, GLfloat *s )
{
for( int i=0; i<_model.size(); i++ )
_model[i]->set_color(o,-1,s[0],s[1],s[2],s[3]);
}
void
AuxGrid :: optimize_cs( int tm )
{
if( _data==NULL ) return;
DATA_TYPE min=_data[tm][0], max=_data[tm][0];
for( int i=1; i<_model[tm]->pt.num(); i++ ) {
if( _data[tm][i]<min )
min=_data[tm][i];
if( _data[tm][i]>max )
max=_data[tm][i];
}
cs.calibrate( min, max );
}
......@@ -9,28 +9,43 @@
#include "Model.h"
#include <vector>
#include "DrawingObjects.h"
#include "VecData.h"
class AuxGrid {
private:
vector<Model *> _model; //!< one model per time
int _num_tm_grid;
int _num_tm_data;
bool _threeD[maxobject];
float _size[maxobject];
int _num_mod;
int _num_tm_grid;
int _num_tm_data;
int _num_mod;
DATA_TYPE **_data;
void read_data_instance( gzFile, int, DATA_TYPE*& );
bool _display;
bool _datafied[maxobject];
bool _surf_fill; //!< if false, draw outline
bool _vol_fill; //!< if false, draw wireframe
bool _autocol;
bool _show[maxobject]; //!< true to show object
public:
AuxGrid( char *fn );
AuxGrid( char *fn, const GLfloat *ptoff=NULL );
~AuxGrid();
void draw( int );
void color( Object_t obj, int s, float r, float g, float b, float a );
GLfloat* color( Object_t obj, int s );
void showobj( Object_t obj, bool f );
bool showobj( Object_t o );
void threeD( Object_t o, bool b ){ _threeD[o] = b; }
bool threeD( Object_t o ){ return _threeD[o]; }
void size( Object_t o, float s ){ _size[o] = s; }
float size( Object_t o ){ return _size[o]; }
int num_tm( return model.size(); );
Colourscale cs;
void draw( int );
void color( Object_t obj, GLfloat *r );
GLfloat* color( Object_t o ){return _model[0]->get_color(o,-1);}
void showobj( Object_t obj, bool b ){_show[obj]=b;}
bool showobj( Object_t o ){return _show[o];}
void threeD( Object_t o, bool b );
bool threeD( Object_t o ){return _model[0]->threeD(o,-1);}
void size( Object_t o, float s );
float size( Object_t o ){return _model[0]->size(o,-1);}
int num_tm(){ return _num_mod; }
void display( bool b ){ _display=b; }
void datify( Object_t o, bool b ){ _datafied[o]=b; }
void surfill( bool b ){ _surf_fill=b; }
void volfill( bool b ){ _vol_fill=b; }
void autocolor( bool b ){ _autocol=b; }
void optimize_cs(int);
};
#endif
......@@ -697,7 +697,7 @@ ClipPlane::ClipPlane( TBmeshWin *tb ) {
} // Fl_Group* Clip2
{ Clip3 = new Fl_Group(5, 250, 185, 220, "Clipping Plane 4");
Clip3->box(FL_UP_BOX);
Clip3->align(Fl_Align(FL_ALIGN_BOTTOM));
Clip3->align(FL_ALIGN_BOTTOM);
{ Fl_Group* o = new Fl_Group(15, 305, 115, 145, "Plane Normal4");
o->box(FL_UP_BOX);
{ xdir3 = new Fl_Value_Input(35, 315, 80, 25, "X:");
......@@ -739,7 +739,7 @@ ClipPlane::ClipPlane( TBmeshWin *tb ) {
} // Fl_Group* Clip3
{ Clip4 = new Fl_Group(195, 250, 185, 220, "Clipping Plane 5");
Clip4->box(FL_UP_BOX);
Clip4->align(Fl_Align(FL_ALIGN_BOTTOM));
Clip4->align(FL_ALIGN_BOTTOM);
{ Fl_Group* o = new Fl_Group(205, 305, 115, 145, "Plane Normal5");
o->box(FL_UP_BOX);
{ xdir4 = new Fl_Value_Input(225, 315, 80, 25, "X:");
......@@ -781,7 +781,7 @@ ClipPlane::ClipPlane( TBmeshWin *tb ) {
} // Fl_Group* Clip4
{ Clip5 = new Fl_Group(385, 250, 185, 220, "Clipping Plane 6");
Clip5->box(FL_UP_BOX);
Clip5->align(Fl_Align(FL_ALIGN_BOTTOM));
Clip5->align(FL_ALIGN_BOTTOM);
{ Fl_Group* o = new Fl_Group(395, 305, 115, 145, "Plane Normal6");
o->box(FL_UP_BOX);
{ xdir5 = new Fl_Value_Input(415, 315, 80, 25, "X:");
......
......@@ -96,7 +96,7 @@ void Connection::draw( int p0, int p1, GLfloat *colour, Colourscale* cs,
if ( p0>=_n || p1>=_n ) return;
if ( (dataopac!=NULL && dataopac->on()) || colour[3]<0.95 ) // data opacity
if ( (dataopac!=NULL && dataopac->on()) || colour[3]<0.95 ) // data opacity
translucency(true);
......
......@@ -100,13 +100,13 @@ DataOpacity::DataOpacity( TBmeshWin *tbmw ) {
minopacval->type(3);
minopacval->value(0.5);
minopacval->callback((Fl_Callback*)cb_minopacval);
minopacval->align(Fl_Align(FL_ALIGN_LEFT));
minopacval->align(FL_ALIGN_LEFT);
} // Fl_Value_Slider* minopacval
{ maxopacval = new Fl_Value_Slider(125, 100, 120, 30, "Maximum Opacity");
maxopacval->type(3);
maxopacval->value(1);
maxopacval->callback((Fl_Callback*)cb_maxopacval);
maxopacval->align(Fl_Align(FL_ALIGN_LEFT));
maxopacval->align(FL_ALIGN_LEFT);
} // Fl_Value_Slider* maxopacval
{ onbut = new Fl_Light_Button(225, 10, 120, 30, "Data Opacity ");
onbut->labelsize(16);
......
......@@ -48,16 +48,16 @@ class Point: public DrawingObj
const GLfloat* pt( int p=0 ){ return _pts+p*3; }
Point(): _pts(NULL), _base1(false) {}
~Point() { if ( _n ) free(_pts); }
const GLfloat* pt( int p ) const { return _pts+p*3; }
const GLfloat* pt( int p ) const { return _pts+p*3; }
void setVis( bool v ){ if (v) _visible=&_allvis; }
void setVis( vector<bool>* v ){ _visible=v; }
void setVis( vector<bool>* v ){ _visible=v; }
bool vis( int n ) const { return (*_visible)[n]; }
bool vis( int n, bool b ) const { (*_visible)[n]=b; }
const vector<bool>* vis() const { return _visible; }
const GLfloat* offset() const { return _offset; }
void offset( const GLfloat*o ) { memcpy(_offset,o,sizeof(GLfloat)*3); }
void base1(bool b){ _base1 = b; }
void add( GLfloat *, int n=1 );
void add( GLfloat *, int n=1 );
const GLfloat* operator[] (int i){ return _pts+3*i; }
private:
GLfloat* _pts; //!< point list
......
......@@ -10,6 +10,8 @@
#include <FL/fl_ask.H>
#include <sstream>
#define MIN_STATIC_CURVE 2
const int setcolour[]=
{
FL_RED, FL_GREEN, FL_BLUE, FL_DARK_MAGENTA,
......@@ -146,7 +148,7 @@ void Graph::copy_curve( int c )
// clear curves
void Graph :: clear_curves()
{
for ( int c=2; c<numset; c++ ) {
for ( int c=MIN_STATIC_CURVE; c<numset; c++ ) {
delete[] xv[c];
delete[] yv[c];
np[c] = 0;
......@@ -262,6 +264,18 @@ Graph :: set_2d_data( const double *x, const double *y, int n, int setno )
}
void
Graph :: rotate()
{
for( int i=MIN_STATIC_CURVE; i<numset; i++ ) {
const double *t = xv[i];
xv[i] = yv[i];
yv[i] = t;
}
scale();
}
//* scale the graph
void Graph::scale()
{
......
......@@ -83,6 +83,7 @@ class Graph : public Fl_Widget
void write(ostream&, int);
int n(){ return numset; }
void to_world( int x, int y, double &wx, double &wy );
void rotate();
private:
const double *xv[max_num_sets], *yv[max_num_sets];
double x0, x1, y0, y1; // data range being plotted
......
......@@ -21,7 +21,7 @@ LIBS = $(FLTK_LD_FLAGS) $(COMMON_LIBS)
INCLUDES = $(FLTK_INC) $(COMMON_INC) -DNOMINMAX
endif
OBJS = Fl_Gl_Tb_Window.o\
OBJS = AuxGrid.o\
ContCable.o\
ClipPlane.o\
Colourscale.o\
......@@ -31,6 +31,7 @@ OBJS = Fl_Gl_Tb_Window.o\
DataOpacity.o\
DrawingObjects.o\
FileType.o\
Fl_Gl_Tb_Window.o\
gl2ps.o\
Graph.o PlotWin.o plottingwin.o\
Hexahedron.o\
......
......@@ -43,6 +43,25 @@ make_face( Face *f, int n, int* orig )
}
/** read in a line from a file, ignoring lines beginning with "#"
*
* \warn not threadsafe
* \return pointer to a static buffer
*/
char *
get_line( gzFile in )
{
const int bufsize=1024;
static char buf[bufsize];
char *retval;
do {
retval = gzgets( in, buf, bufsize );
} while( retval != Z_NULL && buf[0]=='#' );
return retval==Z_NULL?NULL:buf;
}
/** return a new unique region label
*/
int Model::new_region_label()
......@@ -60,9 +79,8 @@ int Model::new_region_label()
}
Model::Model(Colourscale *cs, DataOpacity *dopac ):
_cs(cs),_dataopac(dopac),_base1(false),
_surface(NULL), _vertnrml(NULL),
Model::Model():
_base1(false), _surface(NULL), _vertnrml(NULL),
_numReg(0), _region(NULL), _numVol(0), _vol(NULL)
{
for ( int i=0; i<maxobject; i++ ) {
......@@ -94,7 +112,6 @@ bool Model::read( const char* fnt, bool base1, bool no_elems )
fprintf(stderr, "Unable to read proper points file\n" );
exit(1);
}
_pts = pt.pt();
allvis.resize(pt.num());
allvis.assign(pt.num(), true );
......@@ -638,7 +655,7 @@ void Model :: randomize_color( Object_t obj )
Model::~Model()
{
delete[] _pts;
delete pt.pt();
delete[] _cnnx;
//delete[] _ptnrml;
for ( int i=0; i<_numVol; i++ )
......@@ -664,7 +681,7 @@ void Model::hilight_info( HiLiteInfoWin* hinfo, int* hilight, DATA_TYPE* data )
// Volume ELements
if ( _numVol ) {
int hivol=hilight[Tetrahedron];
int hivol=hilight[VolEle];
sprintf( txt, "@b@C%6dVolume Element: %d of %d", FL_RED, hivol, _numVol );
hinfo->add( txt );
hinfo->add( "nodes:\t" );
......@@ -728,9 +745,9 @@ void Model::hilight_info( HiLiteInfoWin* hinfo, int* hilight, DATA_TYPE* data )
hinfo->add( txt );
}
const GLfloat*offset = pt.offset();
sprintf( txt, "( %.6g, %.6g, %.6g )", _pts[hilight[Vertex]*3]+offset[0],
_pts[hilight[Vertex]*3+1]+offset[1],
_pts[hilight[Vertex]*3+2]+offset[2]);
sprintf( txt, "( %.6g, %.6g, %.6g )", pt.pt()[hilight[Vertex]*3]+offset[0],
pt.pt()[hilight[Vertex]*3+1]+offset[1],
pt.pt()[hilight[Vertex]*3+2]+offset[2]);
hinfo->add( txt );
/*
string reginfo( "in surface: " );
......@@ -813,7 +830,7 @@ void Model::hilight_info( HiLiteInfoWin* hinfo, int* hilight, DATA_TYPE* data )
for ( int j=0; j<_vol[i]->ptsPerObj(); j++ )
if ( tet[j]==hilight[Vertex] ) {
sprintf( txt, "\t%d", i );
if ( tet[j]==hilight[Tetrahedron] )
if ( tet[j]==hilight[VolEle] )
sprintf( txt,"@B%d%s", FL_GRAY, ts=strdup(txt) );
hinfo->add( txt );
for ( int k=0; k<_vol[i]->ptsPerObj(); k++ ) {
......@@ -924,7 +941,7 @@ int Model::number(Object_t a )
for ( int s=0; s<_surface.size(); s++ )
nele += surface(s)->num();
return nele;
case Tetrahedron:
case VolEle:
return _numVol;
case RegionDef:
return _numReg;
......@@ -1041,6 +1058,10 @@ int Model::localElemnum( int gele, int& surf )
/** delete a surface
*
* \param s the number of the surface to delete
*/
void
Model::surfKill( int s )
{
......@@ -1049,3 +1070,85 @@ Model::surfKill( int s )
it++;
_surface.erase(it);
}
#define BUFSIZE 1024
/** read in one instant in time which is part of a element time file
*
* \param pt_in already open point file
* \param elem_in already opened element file
*
* \return
*/
bool Model :: read_instance( gzFile pt_in, gzFile elem_in,
const GLfloat* offset )
{
// read in points
if( pt_in != NULL ) {
int num_pt;
sscanf( get_line(pt_in), "%d", &num_pt );
GLfloat *p = new GLfloat[num_pt*3];
for( int i=0; i< num_pt; i++ ) {
sscanf( get_line(pt_in), "%f %f %f", p+i*3, p+i*3+1, p+i*3+2 );
sub( p+i*3, offset, p+i*3 ); // center wrt fixed model
}
pt.add( p, num_pt );
pt.offset( offset );
pt.setVis( true );
delete[] p;
}
// read in elements
if( elem_in != NULL ) {
int num_elem;
sscanf( get_line(elem_in), "%d", &num_elem );
int *Cxpt = (int *)malloc(num_elem*2*sizeof(int) ), numCx=0;
_vol = new VolElement*[num_elem];
_surface.push_back( new Surfaces( &pt ) );
int n[10];
for( int i=0; i<num_elem; i++ ) {
char type[10];
sscanf( get_line(elem_in),"%s %d %d %d %d %d %d %d %d %d %d",type,
n, n+1, n+2, n+3, n+4, n+5, n+6, n+7, n+8, n+9 );
if( !strcmp( type, "Ln") ) {
Cxpt = (int *)realloc( Cxpt, numCx*sizeof(int)*2+2 );
Cxpt[numCx*2] = n[0];
Cxpt[numCx*2+1] = n[1];
numCx++;
} else if( !strcmp( type, "Tr" ) ) {
_surface.back()->ele().push_back( new Triangle( &pt ) );
_surface.back()->ele().back()->define( n );
} else if( !strcmp( type, "Qd" ) ) {
_surface.back()->ele().push_back( new Quadrilateral( &pt ) );