Commit 9181924e authored by Edward Vigmond's avatar Edward Vigmond

Added FlyBy's (ability to move model smoothly between two states/positions and make images of it)

parent ba57644b
# data file for the Fltk User Interface Designer (fluid)
version 1.0300
header_name {.h}
version 1.0304
header_name {.h}
code_name {.cc}
decl {\#include "TBmeshWin.h"} {private local
}
}
decl {\#include<iostream>} {public local
}
}
decl {\#include "objects.h"} {public local
}
}
decl {using namespace std;} {public local
}
}
decl {\#define NUM_OBJ 7} {public local
}
}
decl {class TBmeshWin;} {public local
}
}
class dataOpac {open
} {
......@@ -54,7 +54,7 @@ return omin+(data-dmin*ofactor);} {}
} {
code {return _on;} {}
}
}
}
class DataOpacity {open
} {
......@@ -122,7 +122,7 @@ maxdatval->value(dop[a].dmax);onbut->value(dop[a]._on);} open
xywh {0 0 100 20}
}
MenuItem {} {
label SurfEle selected
label SurfEle
xywh {0 0 100 20}
}
MenuItem {} {
......@@ -148,13 +148,13 @@ return SurfEle;
else if( a==3 )
return Cable;} {}
}
Function {save(ofstream& ofs)} {open
Function {save(ostream& ofs)} {open selected
} {
code {for( int i=0; i<NUM_OBJ; i++ ) {
ofs << dop[i];
}} {}
}
Function {read(ifstream &ifs)} {open
Function {read(istream &ifs)} {open
} {
code {for( int i=0; i<NUM_OBJ; i++ ) {
ifs >> dop[i];
......@@ -167,16 +167,16 @@ mindatval->value(dop[Vertex].dmin);
maxdatval->value(dop[Vertex].dmax);
onbut->value(dop[Vertex]._on);} {}
}
}
}
Function {operator<<(ostream&ofs,dataOpac&dop)} {open return_type {ostream&}
} {
code {ofs<<dop.dmin<<" "<<dop.dmax<<" "<<dop.omin<<" "<<dop.omax<<" "<<dop._on<<endl;
return ofs;} {}
}
}
Function {operator>>(istream&ifs,dataOpac&dop)} {open return_type {istream&}
} {
code {ifs>>dop.dmin>>dop.dmax>>dop.omin>>dop.omax>>dop._on;
return ifs;} {}
}
}
# data file for the Fltk User Interface Designer (fluid)
version 1.0304
header_name {.h}
code_name {.cc}
decl {\#include "TBmeshWin.h"} {private global
}
decl {\#include "Frame.h"} {private local
}
decl {using namespace std;} {private local
}
decl {\#include <vector>} {public global
}
decl {\#include <algorithm>} {private local
}
decl {\#include <sstream>} {private local
}
decl {class Controls;} {public global
}
decl {\#include "Vector3D.h"} {public global
}
decl {\#include "Quaternion.h"} {public global
}
decl {class TBmeshWin;} {public global
}
class FlyBy {open
} {
Function {FlyBy( TBmeshWin *tb, Controls* cw )} {open
} {
Fl_Window fb_win {
label FlyBy open
xywh {1055 488 340 325} type Double align 4 visible
} {
Fl_Browser fb_list {
callback {if( o->value() )
fb_steps->value(steps[o->value()]);}
xywh {15 15 205 155} type Hold
}
Fl_Button fb_load {
label {@reload}
callback {int currstate = fb_list->value();
if( !currstate ) return;
stringstream sstr(state[currstate]->str());
controls->restore_state( sstr );}
tooltip {load selected state} xywh {15 180 95 35} color 127
}
Fl_Button fb_add {
label {@+}
callback {static int sval=0;
stringstream newlabel;
newlabel << "view " << sval++;
int selstate=fb_list->value();
if( !selstate ) selstate=fb_list->size();
stringstream *sstr = new stringstream;
controls->save_state( *sstr );
state.emplace(state.begin()+selstate+1,sstr);
fb_list->insert(selstate+1, newlabel.str().c_str());
steps.insert(steps.begin()+selstate+1,steps[selstate]);
qRot.insert(qRot.begin()+selstate+1,tbwm->trackball.qRot);
translate.insert(translate.begin()+selstate+1,tbwm->trackball.GetTranslation());
scale.insert(scale.begin()+selstate+1,tbwm->trackball.GetScale());
if( fb_list->size() >= 2 ) {
fb_play->activate();
fb_rec->activate();
}}
tooltip {add current state to list} xywh {127 180 95 35} color 222
}
Fl_Spinner fb_steps {
label {\#steps}
callback {int currstate=fb_list->value();
if( !currstate ) return;
steps[currstate] = o->value();} selected
tooltip {number of frames to interpolate to next state} xywh {235 30 90 25} align 1 maximum 1000 value 10
}
Fl_Button fb_play {
label {@>|}
callback {fly();}
tooltip {play flyby} xywh {10 275 95 35} deactivate
}
Fl_Button fb_rec {
label {@circle}
callback {string base = fb_fname->value();
auto dp = base.find_last_of( "." );
if( dp != string::npos ) {
base.erase(dp,string::npos);
fb_fname->value(base.c_str());
}
fly( base );}
tooltip {play and record flyby} xywh {125 275 95 35} labelcolor 1 deactivate
}
Fl_Return_Button fb_close {
label close
callback {fb_win->hide();}
tooltip {close this dialogue} xywh {235 275 95 35}
}
Fl_Menu_Button fb_del {
label Delete open
tooltip {delete selected state from list} xywh {235 180 95 35} color 90 labelcolor 7 textcolor 7
} {
MenuItem {} {
label really
callback {int selstate = fb_list->value();
if( !selstate ) return;
fb_list->remove(selstate);
state[selstate]->str("");
delete state[selstate];
steps.erase(steps.begin()+selstate);
state.erase(state.begin()+selstate);
qRot.erase(qRot.begin()+selstate);
translate.erase(translate.begin()+selstate);}
xywh {0 0 31 20}
}
}
Fl_Button {} {
label {@8}
callback {int curpos = fb_list->value();
if( curpos<2 ) return;
fb_list->move(curpos-1, curpos);
swap(state[curpos-1],state[curpos]);
swap(steps[curpos-1],steps[curpos]);
swap(qRot[curpos-1],qRot[curpos]);
swap(translate[curpos-1],translate[curpos]);
swap(scale[curpos-1],scale[curpos]);}
tooltip {move selected state up} xywh {235 60 30 30}
}
Fl_Button {} {
label {@2}
callback {int curpos = fb_list->value();
if( !curpos or curpos==fb_list->size() ) return;
fb_list->move(curpos+1, curpos);
swap(state[curpos+1], state[curpos]);
swap(steps[curpos+1], steps[curpos]);
swap(qRot[curpos+1], qRot[curpos]);
swap(translate[curpos+1], translate[curpos]);
swap(scale[curpos+1], scale[curpos]);}
tooltip {move selected state down} xywh {235 95 30 30}
}
Fl_Button {} {
label rename
callback {int selstate = fb_list->value();
if( !selstate ) return;
const char *curname = fb_list->text(selstate);
const char *newname = fl_input("rename state",curname);
if( newname ) fb_list->text(selstate,newname);}
tooltip {rename selected state} xywh {270 70 55 40} color 94
}
Fl_Value_Input fb_delay {
label {delay:}
tooltip {frame delay in ms when playing flyby} xywh {280 147 45 27} minimum 1 maximum 1000 value 100
}
Fl_File_Input fb_fname {
label {output file name base:}
xywh {10 238 230 29} align 1
}
Fl_Button {} {
label browse
callback {const char* fn=fl_file_chooser("Choose output file name base", "*.png",fb_fname->value() );
if( fn != NULL ) fb_fname->value(fn);}
tooltip {select new file name base} xywh {250 236 75 29}
}
Fl_Check_Button fb_tmadv {
label {adv time}
tooltip {advance time with position} xywh {240 120 55 30} down_box DOWN_BOX
}
}
code {tbwm = tb;
controls = cw;
qRot.resize(2);
state.resize(2);
translate.resize(2);
steps.resize(2,10);
scale.resize(2);
fb_fname->value("flyby");} {}
}
decl {TBmeshWin *tbwm;} {private local
}
decl {Controls* controls;} {private local
}
decl {vector<stringstream*> state;} {private local
}
decl {vector<int> steps;} {private local
}
decl {vector<Quaternion> qRot;} {private local
}
decl {vector<V3f> translate;} {private local
}
decl {vector<float> scale;} {private local
}
decl {const char *ofile="flyby";} {private local
}
decl {const char *odir=".";} {private local
}
Function {fly( string fbase = string("") )} {open
} {
code {unsigned int frameno=0;
stringstream sstr(state[1]->str());
controls->restore_state( sstr );
int start_tm = tbwm->time();
for( int i=2; i<=fb_list->size(); i++ ) {
Quaternion start = qRot[i-1];
Quaternion end = qRot[i];
for( int j=0; j<steps[i-1]; j++ ){
float t= float(j)/float(steps[i-1]-1);
tbwm->trackball.qRot = start.Slurp(end, t);
V3f trans = (1-t)*translate[i-1] + t*translate[i];
tbwm->trackball.SetTranslation(trans);
tbwm->trackball.SetScale( (1-t)*scale[i-1] + t*scale[i] );
if( fb_tmadv->value() ) {
if ( !tbwm->set_time( start_tm++ ) )
tbwm->set_time( start_tm=0 );
}
tbwm->redraw();
Fl::flush();
if( fbase.size() ) {
char framename[1024];
sprintf( framename, "%s%06d.png", fbase.c_str(), frameno++ );
Frame frame( tbwm );
frame.write( tbwm->w(), tbwm->h(), framename, tbwm->time() );
} else
usleep( fb_delay->value()*1000 );
}
stringstream s2str(state[i]->str());
controls->restore_state( s2str );
}
tbwm->redraw();
Fl::flush();
if( fbase.size() ) {
char framename[1024];
sprintf( framename, "%s%06d.png", fbase.c_str(), frameno++ );
Frame frame( tbwm );
frame.write( tbwm->w(), tbwm->h(), framename, tbwm->time());
}} {}
}
}
// $Id: Global.h,v 1.2 2005/06/11 16:17:53 vigmond Exp $
// (c) Ingmar Bitter '96-'99
#ifndef _Global_h_ // prevent multiple includes
#define _Global_h_
// include most common libraries
// (no ".h" to ensure use of new C++ standard)
#include <string> // string
#if defined(__sgi) && !defined(__GNUC__)
#include <mstring.h>
#include <assert.h> // assert
#include <stdlib.h> // abort
#include <iostream.h> // cout, cerr, ostream
#else
#include <cassert> // assert
#include <cstdlib> // abort
#include <iostream> // cout, cerr, ostream
#endif
#include <stdio.h> // sprintf
using namespace std;
inline string & operator << (string & s, const string & add) { return s += add; }
inline string & operator << (string & s, const char * add) { string tmp(add); return s<<tmp; }
inline string & operator << (string & s, const int & k) { static char num[30]; sprintf(num,"%i", k); return s+=num; }
inline string & operator << (string & s, const long & k) { static char num[30]; sprintf(num,"%li", k); return s+=num; }
inline string & operator << (string & s, const float & f) { static char num[30]; sprintf(num,"%f", f); return s+=num; }
inline string & operator << (string & s, const double & d) { static char num[30]; sprintf(num,"%f",d); return s+=num; }
//template <class T> inline string & operator << (string & s, const T & t) { s += t; return s; }
//inline char * c_str(const double & d) { static char num[100]; sprintf(num,"%f",d); return num; } // needed to fix above template when using doubles
static const char * const BoolStr[] = {"Oh No ! :-( ",":-) "};
static void Dummy() { cout<<BoolStr[0]; }
typedef unsigned char uchar;
template<class T> inline const T Abs (const T& a) { return (a<0) ? a : -a; }
template<class T> inline const T& Max (const T& a, const T& b) { return (a>b) ? a : b; }
template<class T> inline const T& Min (const T& a, const T& b) { return (a<b) ? a : b; }
template<class T> inline const T& Max (const T& a, const T& b, const T& c) { return (a>b) ? Max(a,c) : Max(b,c); }
template<class T> inline const T& Min (const T& a, const T& b, const T& c) { return (a<b) ? Min(a,c) : Min(b,c); }
template<class T> inline const T& Mid (const T& a, const T& b, const T& c)
{
return (a<b) ? ((b<c)?b:Max(a,c))
: ((b>c)?b:Min(a,c));
}
template<class T> inline const T& Bound(const T&a, const T& b, const T& c)
{
return (a<b) ? ((b<c)?b:c)
: ((b>c)?b:c);
}
#define DB(var,msg) { cerr <<" "<<var<<"="<<msg; }
#define ERROR(msg) { cerr << endl << "###Error### in file " << __FILE__ << " at line " << __LINE__ << endl; cerr << (msg) << endl; cerr << "Exiting ..." << endl; abort(); }
#ifdef sgi
// avoid following warning
// "/usr/include/CC/iostream.h", line 675: remark(1174):
// variable "iostream_init" was declared but never referenced
// } iostream_init ;
#endif
#endif // $Id: Global.h,v 1.2 2005/06/11 16:17:53 vigmond Exp $
// $Id: Global.h,v 1.2 2005/06/11 16:17:53 vigmond Exp $
// (c) Ingmar Bitter '96-'99
#ifndef _Global_h_ // prevent multiple includes
#define _Global_h_
// include most common libraries
// (no ".h" to ensure use of new C++ standard)
#include <string> // string
#if defined(__sgi) && !defined(__GNUC__)
#include <mstring.h>
#include <assert.h> // assert
#include <stdlib.h> // abort
#include <iostream.h> // cout, cerr, ostream
#else
#include <cassert> // assert
#include <cstdlib> // abort
#include <iostream> // cout, cerr, ostream
#endif
#include <stdio.h> // sprintf
using namespace std;
inline string & operator << (string & s, const string & add) { return s += add; }
inline string & operator << (string & s, const char * add) { string tmp(add); return s<<tmp; }
inline string & operator << (string & s, const int & k) { static char num[30]; sprintf(num,"%i", k); return s+=num; }
inline string & operator << (string & s, const long & k) { static char num[30]; sprintf(num,"%li", k); return s+=num; }
inline string & operator << (string & s, const float & f) { static char num[30]; sprintf(num,"%f", f); return s+=num; }
inline string & operator << (string & s, const double & d) { static char num[30]; sprintf(num,"%f",d); return s+=num; }
//template <class T> inline string & operator << (string & s, const T & t) { s += t; return s; }
//inline char * c_str(const double & d) { static char num[100]; sprintf(num,"%f",d); return num; } // needed to fix above template when using doubles
static const char * const BoolStr[] = {"Oh No ! :-( ",":-) "};
static void Dummy() { cout<<BoolStr[0]; }
typedef unsigned char uchar;
template<class T> inline const T Abs (const T& a) { return (a<0) ? a : -a; }
template<class T> inline const T& Max (const T& a, const T& b) { return (a>b) ? a : b; }
template<class T> inline const T& Min (const T& a, const T& b) { return (a<b) ? a : b; }
template<class T> inline const T& Max (const T& a, const T& b, const T& c) { return (a>b) ? Max(a,c) : Max(b,c); }
template<class T> inline const T& Min (const T& a, const T& b, const T& c) { return (a<b) ? Min(a,c) : Min(b,c); }
template<class T> inline const T& Mid (const T& a, const T& b, const T& c)
{
return (a<b) ? ((b<c)?b:Max(a,c))
: ((b>c)?b:Min(a,c));
}
template<class T> inline const T& Bound(const T&a, const T& b, const T& c)
{
return (a<b) ? ((b<c)?b:c)
: ((b>c)?b:c);
}
#define DB(var,msg) { cerr <<" "<<var<<"="<<msg; }
#define ERROR(msg) { cerr << endl << "###Error### in file " << __FILE__ << " at line " << __LINE__ << endl; cerr << (msg) << endl; cerr << "Exiting ..." << endl; abort(); }
#ifdef sgi
// avoid following warning
// "/usr/include/CC/iostream.h", line 675: remark(1174):
// variable "iostream_init" was declared but never referenced
// } iostream_init ;
#endif
#endif // $Id: Global.h,v 1.2 2005/06/11 16:17:53 vigmond Exp $
HOSTMACHINE := $(shell uname)
include make.conf
VTK_LIBDIR =/usr/lib64
VTK_INCDIR =/usr/include/vtk-8.1
#VTK_LIBDIR =/usr/lib64
#VTK_INCDIR =/usr/include/vtk-8.1
FLTK_INC := $(shell fltk-config --use-glut --use-gl --cxxflags)
FLTK_LD_FLAGS := $(shell fltk-config --use-images --use-glut --use-gl --ldflags)
......
#include "PNGwrite.h"
#include <stdlib.h>
PNGwrite :: PNGwrite( FILE *out ) :
width(0),height(0),ctype(PNG_COLOR_TYPE_RGB),
interlace_type(PNG_INTERLACE_NONE),colour_depth(8)
PNGwrite :: PNGwrite( FILE *out ) : fp(out)
{
fp = out;
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL );
if (png_ptr == NULL) {
......
......@@ -43,10 +43,10 @@ class PNGwrite
png_infop info_ptr;
png_colorp cpalette;
FILE *fp;
png_uint_32 width;
png_uint_32 height;
int ctype;
int interlace_type;
int colour_depth;
png_uint_32 width=0;
png_uint_32 height=0;
int ctype=PNG_COLOR_TYPE_RGB;
int interlace_type=PNG_INTERLACE_NONE;
int colour_depth=8;
};
#endif
......@@ -59,6 +59,18 @@ switch (index) { case 0: return w; case 1: return x; case 2: return y; case 3: r
inline const Quaternion GetConjugate() const {
return Quaternion(w,-x,-y,-z);
}
inline const Quaternion operator + (const Quaternion & q) const
{
return Quaternion(w+q.w,x+q.x,y+q.y,z+q.z);
}
inline const Quaternion operator - (const Quaternion & q) const
{
return Quaternion(w-q.w,x-q.x,y-q.y,z-q.z);
}
inline const Quaternion operator * (double a) const
{
return Quaternion(a*w,a*x,a*y,a*z);
}
inline const Quaternion operator * (const Quaternion & q) const
{
return Muliply(q);
......@@ -112,6 +124,38 @@ switch (index) { case 0: return w; case 1: return x; case 2: return y; case 3: r
m[2]= 2.*(x*z-w*y); m[6]= 2.*(y*z+w*x); m[10]=1.-2.*(x*x+y*y); m[14]=0.;
m[3]=0.; m[7]=0.; m[11]=0.; m[15]=1.;
}
inline Quaternion Slurp( Quaternion &final, float t )
{
if( t<0 or t>1 ) return *this;
Quaternion v0 = *this;
Quaternion v1 = final;
v0.Normalize();
v1.Normalize();
// this is from Wikipedia
double dot = v0.w*v1.w+v0.x*v1.x+v0.y*v1.y+v0.z*v1.z;
if (dot < 0.0f) {
v1 = v1*-1;
dot = -dot;
}
const double DOT_THRESHOLD = 0.9995;
if (dot > DOT_THRESHOLD) {
Quaternion result = v0 + (v1-v0)*t;
result.Normalize();
return result*((1-t)*Length() + t*final.Length());
}
double theta_0 = acos(dot);
double theta = theta_0*t;
double sin_theta = sin(theta);
double sin_theta_0 = sin(theta_0);
double s0 = cos(theta) - dot * sin_theta / sin_theta_0;
double s1 = sin_theta / sin_theta_0;
Quaternion on_sph =(v0*s0) + (v1*s1);
return on_sph*((1-t)*Length() + t*final.Length());
}
}
; // class Quaternion
......
......@@ -16,10 +16,12 @@ It uses its own file formats which are simple and easily converted to/from more
* link multiple instances to maintain view, colour scale, etc. across them
* can display time-dependent scalar and vector data
* display auxiliary grids
* fly through model views
## VTU format
Preliminary support for reading the VTK format for unstructured grids, VTU, has been included. You need to edit the **Makefile** manually to specify the directory containing the dynamically linked libraries (`VTK_LIBDIR`) and the directory with the VTK header files (`VTK_INCDIR`)
Preliminary support for reading the VTK format for unstructured grids, VTU, has been included. You need to edit the **Makefile** manually to specify the directory containing the dynamically linked libraries (`VTK_LIBDIR`) and the directory with the VTK header files (`VTK_INCDIR`). They
are commented out by default.
For Mac users, the easiest is to install `vtk` via [homebrew](https://brew.sh/): `brew install vtk`
......
......@@ -166,7 +166,7 @@ void Trackball::save( const char *fn )
}
// save the transform into a file
void Trackball::save( ofstream& xfrmfile )
void Trackball::save( ostream& xfrmfile )
{
xfrmfile << scale << endl;
xfrmfile << v3f_trans.X() <<" "<<v3f_trans.Y() <<" " <<v3f_trans.Z()<< endl;
......@@ -185,7 +185,7 @@ void Trackball::read( const char *fn )
}
// read the tranform from a file
void Trackball::read( ifstream& xfrmfile )
void Trackball::read( istream& xfrmfile )
{
xfrmfile >> scale;
xfrmfile >> v3f_trans;
......
......@@ -72,6 +72,7 @@ class Trackball
inline void Rotation(Quaternion spin) { qRot = spin*qRot; }
inline const Quaternion & GetRotation( ) { return qRot; }
// trackball/scene translation
inline void SetTranslation( V3f trans ) { v3f_trans = trans; }
inline void SetTranslation(float x, float y, float z) { v3f_trans(x, y, z); }
inline const V3f & GetTranslation( ) { return v3f_trans; }
void DoTransform();
......@@ -80,8 +81,8 @@ class Trackball
float DepthOnSphere(float x, float y);
void save( const char * );
void read( const char * );
void save( ofstream& );
void read( ifstream& );
void save( ostream& );
void read( istream& );
}
; // Trackball
......
......@@ -2,8 +2,8 @@
// (c) Ingmar Bitter '96-'99
// $Id: Vector3D.C,v 1.2 2005/09/21 20:08:05 vigmond Exp $
#include <math.h>
#include "Vector3D.h"
#include "math.h"
#include <sstream>
template<>
......
......@@ -5,6 +5,7 @@
#ifndef _Vector3D_h_ // prevent multiple includes
#define _Vector3D_h_
#include <math.h>