VectorFieldLines.cpp

This is tutorial demostrates how to access a vector field to draw some openGL lines. For accessing the data the fiber data model is used, which is located in vish's fish (= Fiber Vish). You should be familiar with VRenderObject and the use of display lists in vish.

To see the VectorFieldLines module connected to the CouetteFlow start it by using the .vis file.

../../../bin/vish VectorFieldLines.vis

There's an issue with updating at the beginning. So you have to move the mouse shortly over the LineLength QTWidget or change the value, before you can see the lines in the viewer.

See also:
Required tutorials: - Simple3DObject.cpp - DisplayListObject.cpp - SimpleCoords.cpp

Further tutorials: - InterpolatedVector.cpp

00001 #include <ocean/GLvish/VRenderObject.hpp>
00002 
00003 #include <fish/lakeview/bone/FishSlice.hpp>
00004 #include <fish/lakeview/bone/FishField.hpp>
00005 
00006 #include <field/DirectProductArray.hpp>
00007 #include <ocean/GLvish/BoundingBox.hpp>
00008 
00009 using namespace Wizt;
00010 using namespace Fiber;
00011 
00012 
00035 class VectorFieldLines : public virtual VRenderObject,  virtual public Fish<Slice>, virtual public Fish<Field>
00036 {
00037 public:
00038         // Shortcut some Datatypes used to acess coordinate and vector data.
00039         // Note that coordinates can come procedural or numerical and need different 
00040         // data types to be handled.
00041         typedef MemArray<3, Eagle::tvector3>           VectorArray_t; 
00042         typedef MemArray<3, Eagle::point3>             CoordsArray_t; 
00043         typedef DirectProductMemArray<Eagle::point3>   ProceduralArray_t; 
00044 
00045 
00046         TypedSlot<double> LineLength;
00047         TypedSlot<int>    LineWidth;
00048 
00049         // Inner class to save local state Information. Besides the control parameters also 
00050         // pointers to the vector and coordinate data are saved here.
00051         struct  MyState : State
00052         {
00053                 double line_length;
00054                 double line_width;
00055                 RefPtr<Field> Coords,
00056                               Vectors;
00057 
00058                 bool changed( const double ll, const int lw)
00059                 {
00060                         if ( ll != line_length || lw != line_width)
00061                                 return true; 
00062                         return false;
00063                 }
00064                 
00065                 void update( const double ll, const int lw)
00066                 {
00067                         line_length = ll; 
00068                         line_width  = lw;
00069                 }
00070         };
00071 
00072         override RefPtr<State> newState() const
00073         {
00074                 return new MyState();
00075         }
00076 
00077 
00078 
00079         VectorFieldLines(const string&name, int p, const RefPtr<VCreationPreferences>&VP)
00080         : VRenderObject(name, p, VP)
00081         , Fish<VObject>(this)
00082         , Fish<Field>("datafield")
00083         , LineLength(this, "LineLength", 0.1)
00084         , LineWidth(this, "LineWidth", 1)
00085         {
00086                 LineLength.setProperty("max", 10.0); 
00087                 LineWidth.setProperty("max", 10); 
00088 
00089                 acceptType<Eagle::tvector3>();
00090         }
00091 
00092 
00093         override bool update( VRequest&R, double precision );
00094         override void render( VRenderContext&R ) const;
00095 };
00096 
00097 
00098 
00103 bool VectorFieldLines::update( VRequest&R, double precision )
00104 {
00105         printf("VectorFieldLines::update(): updating\n"); 
00106 
00107 FieldSelector FS = getFieldSelector(R);
00108 
00109 // get the grid of the fiber bundle 
00110 RefPtr<Grid>  G = FS.GridSource();
00111         if (!G)
00112         {
00113                 if (RefPtr<MyState> S = getState(R) )
00114                         {
00115                                 S-> Coords = NullPtr(); 
00116                                 S-> Vectors = NullPtr();
00117                         } 
00118                 return true;
00119         } 
00120 
00121 // get the coordinates of the grid
00122 RefPtr<Field> Coords  = G->CartesianPositions(); 
00123         if (!Coords)  { puts("VectorFieldLines::update(): No coord field!"); return true; } 
00124 
00125 
00126 // get the vector data of the grid 
00127 RefPtr<Field> Vectors = FS.getField() ;
00128         if (!Vectors) { puts("VectorFieldLines::update(): No vector field!"); return true; } 
00129 
00130 
00131 // get the actual state object
00132 RefPtr<MyState> S = myState(R); 
00133 
00134         assert(S); 
00135 
00136 // save coordinates and vector data into the state
00137         S -> Coords = Coords; 
00138         S -> Vectors = Vectors; 
00139 
00140         return true;
00141 }
00142 
00143 
00144 void VectorFieldLines::render( VRenderContext& Context ) const
00145 {
00146         //resetBBox(Context);
00147 
00148         printf("VectorFieldLines::render(): starting to render\n");
00149 double line_length = 0.0; 
00150 int line_width = 2; 
00151 
00152         LineLength << Context >> line_length; 
00153         LineWidth  << Context >> line_width; 
00154 
00155         glEnable(GL_DEPTH_TEST); 
00156         glDisable(GL_LIGHTING); 
00157 
00158         // get current state
00159         RefPtr<MyState>  state = myState(Context); 
00160 
00161         // return if no valid coord and vector data is available 
00162         if(!state)
00163         {
00164                 printf("VectorFieldLines::render(): Invalid State!\n");
00165                 return; 
00166         }
00167         if (!state->Coords)
00168         {
00169                 printf("VectorFieldLines::render(): Invalid Coordinates!\n");
00170                 return; 
00171         }
00172         if (!state->Vectors)
00173         {
00174                 printf("VectorFieldLines::render(): Invalid Vectors!\n");
00175                 return; 
00176         } 
00177 
00178         
00179         RefPtr<ValueSet> RenderParameterSpace = new ValueSet(); 
00180 
00181         RefPtr<DisplayList> DL; 
00182         try{
00183         DL = Context(*state)(this)( RenderParameterSpace ); 
00184         } 
00185         catch(...){}
00186         if (DL && !state->changed(line_length, line_width) )   //call display list if availlable
00187         {
00188                 if(DL->call())
00189                 {
00190                         printf("VectorFieldLines::render(): Called List\n");
00191                         return;
00192                 } 
00193         } 
00194         else                                                   //prepare display list
00195         {
00196                 DL = Context[*state][this][ RenderParameterSpace ]; 
00197                 if (!DL) throw "VectorFieldLines::render() No Display List!?"; 
00198 
00199                 state->update( line_length, line_width); 
00200 
00201 
00202                 // Get the coordinates saved in actual state. 
00203                 // They can come as procedural or numerical coordinates. 
00204                 // Be prepared for both types, because they need different handling.
00205                 RefPtr<ProceduralArray_t>   PCrds = state->Coords->getData(); 
00206                 RefPtr<CoordsArray_t>       Crds  = state->Coords->getData(); 
00207                 if (!(Crds || PCrds))
00208                 {
00209                         printf("VectorFieldLines::render(): Did not find any coordinates :  %s\n",
00210                                Typename( state->Coords->getType() ).c_str() ); 
00211                         return;
00212                 } 
00213 
00214                 if (PCrds) // found procedural coordinates
00215                 {
00216                 point Start = PCrds->first(); 
00217                 point End   = PCrds->last(); 
00218                         setBoundingBall(Context, new BoundingBox(Start, End) ); 
00219                         printf("VectorFieldLines::render(): got procedural coordinates\n" );
00220                 } 
00221                 if (Crds)  // found numerical coordinates
00222                 {
00223                 point Start = Crds->first(); 
00224                 point End   = Crds->last(); 
00225                         setBoundingBall(Context, new BoundingBox(Start, End) ); 
00226                         printf("VectorFieldLines::render(): got numerical coordinates\n" ); 
00227                 } 
00228 
00229 
00230                 // get vectors
00231                 RefPtr<VectorArray_t> Vctrs = state->Vectors->getData(); 
00232                 if (!Vctrs)
00233                 {
00234                         printf("VectorFieldLines::render(): No vectors\n" ); 
00235                         return;
00236                 } 
00237                 else
00238                         printf("VectorFieldLines::render(): got Vectors data\n" ); 
00239 
00240 
00241         // create a Multiindex for traversing coordinate and vector data. 
00242         MultiIndex<3> M; 
00243 
00244         glCompile( *DL ) 
00245                 {
00246                         printf("VectorFieldLines::render(): compiling new list\n");
00247                         glLineWidth(line_width); 
00248                         glBegin(GL_LINES); 
00249                         glColor3f(1.0,1.0,1.0); 
00250 
00251                         do
00252                         {
00253                         point Vertex, VertexTo; 
00254 
00255                                 if (Crds) // get numerical coordinate
00256                                 {
00257                                         Vertex = (*Crds)[M];
00258                                 }
00259                                 else      // get procedural coordinate
00260                                 {
00261                                         Vertex = (*PCrds)[M];
00262                                 } 
00263 
00264                                 // get vector of same index as according coordinate, should always be consistent!
00265                         tvector Vector = (*Vctrs)[M]; 
00266                                 VertexTo = Vertex + Vector * line_length;
00267                                 //Vector.normalize(); 
00268                                 //glColor3f(norm(Vector)*line_length, 1, 1); 
00269                                 glVertex(Vertex); 
00270                                 glVertex(VertexTo); 
00271 
00272                                 //embrace( Context, Vertex ); 
00273                                 //embrace( Context, VertexTo ); 
00274                                 
00275                         }
00276                         while( M.inc( (*Vctrs).Size()  ) ); // proceed to next Multiindex 
00277                         
00278                         glEnd();
00279  
00280                 } 
00281         //closeBBox(Context);
00282         }
00283 }
00284 
00285 
00286 static Ref<VCreator<VectorFieldLines, AcceptList<Fiber::BundlePtr> > > myCreator("Tutorial/VectorFieldLines");
00287 
00288 VISH_DEFAULT_INIT

Generated on Thu Apr 2 18:58:49 2009 for VISHTutorial by  doxygen 1.4.7