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.
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