fish/interpolatedvector/InterpolatedVector.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

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