Start e.g.: ../../../bin/vish InterpolatedVector.vis
Again, move the mouse over a InterpolatedVector QTWidget or change a paramter slightly, to make it render.
further tutorials: - SimpleStreamline.cpp
00001 #include <ocean/GLvish/VRenderObject.hpp> 00002 #include <fish/lakeview/bone/FishSlice.hpp> 00003 #include <fish/lakeview/bone/FishField.hpp> 00004 00005 #include <field/DirectProductArray.hpp> 00006 #include <ocean/GLvish/BoundingBox.hpp> 00007 00008 #include <fish/fiber/vector/Interpolate.hpp> 00009 #include <fish/fiber/vector/LinearIpol.hpp> 00010 00011 using namespace Wizt; 00012 using namespace Fiber; 00013 00014 00031 class InterpolatedVector : public virtual VRenderObject, public virtual Fish<Slice>, public virtual Fish<Field> 00032 { 00033 public: 00034 typedef MemArray<3, Eagle::tvector3> VectorArray_t; 00035 typedef MemArray<3, Eagle::point3> CoordsArray_t; 00036 typedef DirectProductMemArray<Eagle::point3> ProceduralArray_t; 00037 00038 00039 TypedSlot<double> LineLength; 00040 TypedSlot<int> LineWidth; 00041 00042 TypedSlot<double> X, 00043 Y, 00044 Z; 00045 00046 // Inner class to save local state Information. Besides the control parameters also 00047 // pointers to the vector and coordinate data are saved here. 00048 struct MyState : State 00049 { 00050 double line_length; 00051 double line_width; 00052 RefPtr<Field> Coords, 00053 Vectors; 00054 double x, y, z; 00055 tvector vec; 00056 point pos; 00057 00058 bool changed( const double ll, const int lw, const double xx, const double yy, const double zz) 00059 { 00060 if ( ll != line_length || lw != line_width || xx != x || yy != y || zz != z) 00061 return true; 00062 return false; 00063 } 00064 00065 void update( const double ll, const int lw, const double xx, const double yy, const double zz) 00066 { 00067 line_length = ll; 00068 line_width = lw; 00069 x = xx; 00070 y = yy; 00071 z = zz; 00072 } 00073 }; 00074 00075 override RefPtr<State> newState() const 00076 { 00077 return new MyState(); 00078 } 00079 00080 00081 00082 InterpolatedVector(const string&name, int p, const RefPtr<VCreationPreferences>&VP) 00083 : VRenderObject(name, p, VP) 00084 , Fish<VObject>(this) 00085 , Fish<Field>("datafield") 00086 , LineLength(this, "LineLength", 0.1) 00087 , LineWidth(this, "LineWidth", 1) 00088 , X(this, "X", 0.0) 00089 , Y(this, "Y", 0.0) 00090 , Z(this, "Z", 0.0) 00091 { 00092 LineLength.setProperty("max", 10.0); 00093 LineWidth.setProperty("max", 10); 00094 X.setProperty("max", 1.0); 00095 Y.setProperty("max", 1.0); 00096 Z.setProperty("max", 1.0); 00097 00098 acceptType<Eagle::tvector3>(); 00099 } 00100 00101 00102 override bool update( VRequest&R, double precision ); 00103 override void render( VRenderContext&R ) const; 00104 }; 00105 00106 00107 00112 bool InterpolatedVector::update( VRequest&R, double precision ) 00113 { 00114 printf("InterpolatedVector::update(): updating\n"); 00115 00116 FieldSelector FS = getFieldSelector(R); 00117 00118 // get the grid of the fiber bundle 00119 RefPtr<Grid> G = FS.GridSource(); 00120 if (!G) 00121 { 00122 if (RefPtr<MyState> S = getState(R) ) 00123 { 00124 S-> Coords = NullPtr(); 00125 S-> Vectors = NullPtr(); 00126 } 00127 return true; 00128 } 00129 00130 // get the coordinates of the grid 00131 RefPtr<Field> Coords = G->CartesianPositions(); 00132 if (!Coords) { puts("InterpolatedVector::update(): No coord field!"); return true; } 00133 00134 00135 // get the vector data of the grid 00136 RefPtr<Field> Vectors = FS.getField() ; 00137 if (!Vectors) { puts("InterpolatedVector::update(): No vector field!"); return true; } 00138 00139 00140 // get the actual state object 00141 RefPtr<MyState> S = myState(R); 00142 00143 assert(S); 00144 00145 // save coordinates and vector data into the state 00146 S -> Coords = Coords; 00147 S -> Vectors = Vectors; 00148 00149 RefPtr<VectorArray_t> Vctrs = Vectors->getData(); 00150 00151 if( !Vctrs) 00152 { 00153 printf("InterpolatedVector::update(): Could get vector field data yet!\n"); 00154 return false; 00155 } 00156 else 00157 printf("InterpolatedVector::update(): Gotvector field data!\n"); 00158 00159 RefPtr<ProceduralArray_t> PCrds = Coords->getData(); 00160 RefPtr<CoordsArray_t> Crds = Coords->getData(); 00161 if (!(Crds || PCrds)) 00162 { 00163 printf("InterpolatedVector::update(): Did not find any coordinates : %s\n", 00164 Typename( Coords->getType() ).c_str() ); 00165 return false; 00166 } 00167 00168 00169 // Now do the Interpolation of the Coordinates 00170 00171 // Get index Range of Data (and Coordinates) 00172 MultiIndex<3> FieldSize = Vctrs->Size(); 00173 00174 00175 double x, y, z; 00176 point position; 00177 point vertex; 00178 00179 // Get user specified position ranging from 0 to 1.0 in each coordinate covering the whole dataset 00180 X << R >> x; 00181 Y << R >> y; 00182 Z << R >> z; 00183 00184 // Clamp wrong inputs 00185 for (int i = 0; i < 3; i++) 00186 { 00187 if( position[i] < 0 ) 00188 position[i] = 0.0; 00189 00190 if( position[i] >= FieldSize[i] ) 00191 position[i] = FieldSize[i] - 1; 00192 } 00193 00194 // Calculate float index for coordinates and data. (Unnormalize) 00195 position = x * FieldSize[0] - 1, y * FieldSize[1] -1 , z * FieldSize[2] - 1; 00196 00197 point VoxelIntervalFloor; 00198 point VoxelIntervalCeil; 00199 00200 tvector Unit[3]; 00201 Unit[0] = 1.0, 0.0, 0.0; 00202 Unit[1] = 0.0, 1.0, 0.0; 00203 Unit[2] = 0.0, 0.0, 1.0; 00204 00205 tvector VoxelIntervalSpan; 00206 00207 MultiIndex<3> FloorIntervalIndex; 00208 00209 // Get index of lower coordinate 00210 FloorIntervalIndex = (int)floor(position[0]), (int)floor(position[1]), (int)floor(position[2]); 00211 00212 if (PCrds) // found procedural coordinates 00213 { 00214 // Get position at lower coordinate 00215 VoxelIntervalFloor = (*PCrds)[FloorIntervalIndex]; 00216 // Increase index in each direction by 1 00217 FloorIntervalIndex[0]++; 00218 FloorIntervalIndex[1]++; 00219 FloorIntervalIndex[2]++; 00220 // Get position at upper coordinate 00221 VoxelIntervalCeil = (*PCrds)[FloorIntervalIndex]; 00222 00223 00224 } 00225 if (Crds) // found numerical coordinates 00226 { 00227 // Get position at lower coordinate 00228 VoxelIntervalFloor = (*Crds)[FloorIntervalIndex]; 00229 // Increase index in each direction by 1 00230 FloorIntervalIndex[0]++; 00231 FloorIntervalIndex[1]++; 00232 FloorIntervalIndex[2]++; 00233 // Get position at lower coordinate 00234 VoxelIntervalCeil = (*Crds)[FloorIntervalIndex]; 00235 } 00236 00237 // Calculate diagonal of voxel 00238 VoxelIntervalSpan = VoxelIntervalCeil - VoxelIntervalFloor; 00239 00240 00241 vertex = VoxelIntervalFloor; 00242 00243 for(int i = 0; i<3; i++) 00244 { 00245 vertex += ( VoxelIntervalSpan[i] * (position[i] - FloorIntervalIndex[i])) * Unit[i]; 00246 } 00247 00248 S->pos = vertex; 00249 00250 Interpolate<3, tvector, LinearIpol<tvector> > VecField(*Vctrs, position); 00251 00252 S->vec = VecField.eval(); 00253 00254 00255 00256 00257 return true; 00258 } 00259 00260 00261 void InterpolatedVector::render( VRenderContext& Context ) const 00262 { 00263 00264 00265 00266 //resetBBox(Context); 00267 00268 printf("InterpolatedVector::render(): starting to render\n"); 00269 double line_length = 0.0; 00270 int line_width = 2; 00271 double x, y, z; 00272 00273 LineLength << Context >> line_length; 00274 LineWidth << Context >> line_width; 00275 00276 if(line_width < 1) 00277 line_width = 1; 00278 X << Context >> x; 00279 Y << Context >> y; 00280 Z << Context >> z; 00281 00282 glEnable(GL_DEPTH_TEST); 00283 glDisable(GL_LIGHTING); 00284 00285 // diplay list 00286 RefPtr<MyState> state = myState(Context); 00287 00288 // return if no valid coord and vector data is available 00289 if(!state) 00290 { 00291 printf("InterpolatedVector::render(): Invalid State!\n"); 00292 return; 00293 } 00294 if (!state->Coords) 00295 { 00296 printf("InterpolatedVector::render(): Invalid Coordinates!\n"); 00297 return; 00298 } 00299 if (!state->Vectors) 00300 { 00301 printf("InterpolatedVector::render(): Invalid Vectors!\n"); 00302 return; 00303 } 00304 00305 00306 RefPtr<ValueSet> RenderParameterSpace = new ValueSet(); 00307 RefPtr<DisplayList> DL; 00308 try{ 00309 DL = Context(*state)(this)( RenderParameterSpace ); 00310 } 00311 catch(...){} 00312 if (DL && !state->changed(line_length, line_width, x, y, z) ) //call display list if availlable 00313 { 00314 if(DL->call()) 00315 { 00316 printf("InterpolatedVector::render(): Called List\n"); 00317 return; 00318 } 00319 } 00320 else //prepare display list 00321 { 00322 DL = Context[*state][this][ RenderParameterSpace ]; 00323 if (!DL) throw "InterpolatedVector::render() No Display List!?"; 00324 00325 state->update( line_length, line_width, x, y, z); 00326 00327 00328 // Get the coordinates saved in actual state. 00329 // They can come as procedural or numerical coordinates. 00330 // Be prepared for both types, because they need different handling. 00331 RefPtr<ProceduralArray_t> PCrds = state->Coords->getData(); 00332 RefPtr<CoordsArray_t> Crds = state->Coords->getData(); 00333 if (!(Crds || PCrds)) 00334 { 00335 printf("InterpolatedVector::render(): Did not find any coordinates : %s\n", 00336 Typename( state->Coords->getType() ).c_str() ); 00337 return; 00338 } 00339 00340 if (PCrds) // found procedural coordinates 00341 { 00342 point Start = PCrds->first(); 00343 point End = PCrds->last(); 00344 setBoundingBall(Context, new BoundingBox(Start, End) ); 00345 printf("InterpolatedVector::render(): got procedural coordinates\n" ); 00346 } 00347 if (Crds) // found numerical coordinates 00348 { 00349 point Start = Crds->first(); 00350 point End = Crds->last(); 00351 setBoundingBall(Context, new BoundingBox(Start, End) ); 00352 printf("InterpolatedVector::render(): got numerical coordinates\n" ); 00353 } 00354 00355 00356 // // get vectors 00357 // RefPtr<VectorArray_t> Vctrs = state->Vectors->getData(); 00358 // if (!Vctrs) 00359 // { 00360 // printf("InterpolatedVector::render(): No vectors\n" ); 00361 // return; 00362 // } 00363 // else 00364 // printf("InterpolatedVector::render(): got Vectors data\n" ); 00365 00366 00367 // // create a Multiindex for traversing coordinate and vector data. 00368 // MultiIndex<3> M; 00369 00370 00371 glCompile( *DL ) 00372 { 00373 glLineWidth(line_width); 00374 glBegin(GL_LINES); 00375 glColor3f(z, 0.0, x); 00376 glVertex(state->pos); 00377 glColor3f(1-z, 0.0, 1-x); 00378 glVertex(state->pos + state->vec * line_length); 00379 glEnd(); 00380 // printf("InterpolatedVector::render(): compiling new list\n"); 00381 // glLineWidth(line_width); 00382 // glBegin(GL_LINES); 00383 // glColor3f(1.0,1.0,1.0); 00384 00385 // do 00386 // { 00387 // point Vertex; 00388 00389 // if (Crds) // get numerical coordinate 00390 // { 00391 // Vertex = (*Crds)[M]; 00392 // } 00393 // else // get procedural coordinate 00394 // { 00395 // Vertex = (*PCrds)[M]; 00396 // } 00397 00398 // // get vector of same index as according coordinate, should always be consistent! 00399 // tvector Vector = (*Vctrs)[M]; 00400 // //Vector.normalize(); 00401 // //glColor3f(norm(Vector)*line_length, 1, 1); 00402 // glVertex(Vertex); 00403 // glVertex(Vertex + Vector * line_length); 00404 00405 // //embrace( Context, Vertex ); 00406 // } 00407 // while( M.inc( (*Vctrs).Size() ) ); // proceed to new Multiindex 00408 00409 // glEnd(); 00410 00411 } 00412 00413 //closeBBox(Context); 00414 } 00415 00416 } 00417 00418 00419 static Ref<VCreator<InterpolatedVector, AcceptList<Fiber::BundlePtr> > > myCreator("Tutorial/InterpolatedVector"); 00420 00421 VISH_DEFAULT_INIT