00001 #include <ocean/GLvish/VRenderObject.hpp>
00002 #include <fish/lakeview/bone/FishSlice.hpp>
00003 #include <fish/lakeview/bone/FishField.hpp>
00004
00005 #include <ocean/GLvish/Colormap.hpp>
00006
00007 #include <eagle/FixedArray.hpp>
00008 #include <field/DirectProductArray.hpp>
00009 #include <ocean/GLvish/BoundingBox.hpp>
00010
00011 #include <fish/fiber/vector/Interpolate.hpp>
00012 #include <fish/fiber/vector/LinearIpol.hpp>
00013 #include <fish/fiber/vector/CubicIpol.hpp>
00014
00015 #include <ocean/plankton/VOperatorCache.hpp>
00016
00017
00018
00019 using namespace Wizt;
00020 using namespace Fiber;
00021
00039 class SimpleStreamline : public virtual VRenderObject, public virtual Fish<Slice>, public virtual Fish<Field>
00040 {
00041 public:
00042 typedef MemArray<3, tvector> VectorArray_t;
00043 typedef MemArray<3, point> CoordsArray_t;
00044 typedef DirectProductMemArray<point> ProceduralArray_t;
00045
00046 typedef FixedArray<float,3> rgb;
00047
00048
00049 typedef std::vector<point> Line_t;
00050
00051
00052 typedef VOperatorCache<std::vector<Line_t> > OpCache_t;
00053
00054 TypedSlot<int> LineLength;
00055 TypedSlot<int> LineWidth;
00056 TypedSlot<int> PointSize;
00057 TypedSlot<int> LineNumber;
00058 TypedSlot<double> StepSize;
00059 TypedSlot<double> FanDelta;
00060
00061 TypedSlot<double> X,
00062 Y,
00063 Z;
00064
00065 struct MyState : State
00066 {};
00067
00068 override RefPtr<State> newState() const
00069 {
00070 return new MyState();
00071 }
00072
00073 SimpleStreamline(const string&name, int p, const RefPtr<VCreationPreferences>&VP)
00074 : VRenderObject(name, p, VP)
00075 , Fish<VObject>(this)
00076 , Fish<Field>("datafield")
00077 , LineLength(this, "LineLength", 40)
00078 , LineWidth(this, "LineWidth", 2)
00079 , PointSize(this, "PointSize", 2)
00080 , LineNumber(this, "LineNumber", 10)
00081 , StepSize(this, "StepSize", 0.1)
00082 , FanDelta(this, "FanDelta", 0.05)
00083 , X(this, "X", 0.271)
00084 , Y(this, "Y", 0.294)
00085 , Z(this, "Z", 0.531)
00086 {
00087 LineLength.setProperty("max", 100);
00088 LineLength.setProperty("min", 1);
00089 LineWidth.setProperty("max", 20);
00090 PointSize.setProperty("max", 20);
00091 LineNumber.setProperty("min", 1);
00092 X.setProperty("max", 1.0);
00093 Y.setProperty("max", 1.0);
00094 Z.setProperty("max", 1.0);
00095
00096 acceptType<Eagle::tvector3>();
00097 }
00098
00099
00100 override bool update( VRequest&R, double precision );
00101 override void render( VRenderContext&R ) const;
00102
00103 void getCoordinates(const point& float_index, point& position_cordinates);
00104 };
00105
00106
00110 bool SimpleStreamline::update( VRequest&R, double precision )
00111 {
00112 printf("SimpleStreamline::update(): updating\n");
00113
00114 FieldSelector FS = getFieldSelector(R);
00115
00116
00117 RefPtr<Grid> G = FS.GridSource();
00118 if (!G)
00119 return true;
00120
00121
00122 RefPtr<Field> Coords = G->CartesianPositions();
00123 if (!Coords) { puts("SimpleStreamline::update(): No coord field!"); return true; }
00124
00125
00126
00127 RefPtr<Field> Vectors = FS.getField();
00128 if (!Vectors) { puts("SimpleStreamline::update(): No vector field!"); return true; }
00129
00130
00131
00132
00133
00134 RefPtr<OpCache_t>&OC = OpCache_t::retrieve( *Vectors ) [ self() ];
00135 if (!OC) OC = new OpCache_t();
00136
00137
00138 RefPtr<VectorArray_t> Vctrs = Vectors->getData();
00139 if( !Vctrs)
00140 {
00141 printf("SimpleStreamline::update(): Could get vector field data yet!\n");
00142 if (OC)
00143 {
00144 OC->resize( 0 );
00145 GLCache::clear( *OC );
00146 }
00147 return true;
00148 }
00149 else
00150 printf("SimpleStreamline::update(): Gotvector field data!\n");
00151
00152 RefPtr<ProceduralArray_t> PCrds = Coords->getData();
00153 RefPtr<CoordsArray_t> Crds = Coords->getData();
00154 if (!(Crds || PCrds))
00155 {
00156 printf("SimpleStreamline::update(): Did not find any coordinates : %s\n",
00157 Typename( Coords->getType() ).c_str() );
00158 return true;
00159 }
00160
00161
00162
00163 RefPtr<ValueSet> Changeables = new ValueSet();
00164
00165 Changeables & R += X, Y, Z, LineLength, PointSize, StepSize, FanDelta, LineNumber;
00166
00167
00168 if (OC->unchanged( Changeables ) )
00169 {
00170 printf("SimpleStreamline::update(): Line Calc Skipped, Lines in Cache...\n");
00171 return true;
00172 }
00173
00174
00175 int line_number = 1;
00176 LineNumber << R >> line_number;
00177
00178
00179 OC->resize( line_number );
00180 GLCache::clear( *OC );
00181
00182
00183
00184 MultiIndex<3> FieldSize = Vctrs->Size();
00185
00186
00187 double x, y, z;
00188 point float_index;
00189 point max_float_index;
00190 point vertex;
00191 int line_length;
00192 double hh;
00193 double fan_delta;
00194
00195 LineLength << R >> line_length;
00196 StepSize << R >> hh;
00197 FanDelta<< R >> fan_delta;
00198
00199
00200 X << R >> x;
00201 Y << R >> y;
00202 Z << R >> z;
00203
00204 max_float_index = FieldSize[0] - 1, FieldSize[1] - 1, FieldSize[2] - 1;
00205 float_index = x * FieldSize[0] - 1, y * FieldSize[1] -1 , z * FieldSize[2] - 1;
00206
00207
00208 for (int i = 0; i < 3; i++)
00209 {
00210 if( float_index[i] < 0 )
00211 float_index[i] = 0.0;
00212
00213 if( float_index[i] >= FieldSize[i] )
00214 float_index[i] = FieldSize[i] - 1;
00215 }
00216
00217
00218
00219 point DomainStart = PCrds->first();
00220 point DomaintEnd = PCrds->last();
00221
00222 tvector DomainDiagonal = DomaintEnd - DomainStart;
00223
00224
00225
00226 std::vector<point> StartVertex;
00227 StartVertex.resize(line_number);
00228
00229
00230
00231
00232 StartVertex[0] = ( DomainStart + tvector(component_wise( component_wise(DomainDiagonal, max_float_index, Eagle::Operator<'/'>() ), float_index, Eagle::Operator<'*'>() ) ) );
00233
00234
00235 tvector CurrentDir;
00236 point CurrentVertex;
00237 point CurrentFloatIndex;
00238 tvector FanOffset;
00239 FanOffset = 1, 0, 0;
00240
00241 resetBBox( R );
00242 embrace( R, StartVertex[0]);
00243
00244
00245 for(int l = 0; l < line_number; l++)
00246 {
00247
00248 StartVertex[l] = StartVertex[0] + FanOffset * l * fan_delta;
00249
00250 Line_t&myLine = (*OC)[l];
00251 myLine.clear();
00252
00253 for(int i = 0; i < line_length; i++)
00254 {
00255 if (i == 0)
00256 {
00257 CurrentVertex = StartVertex[l];
00258
00259
00260
00261 Interpolate<3, tvector, CubicIpol <tvector> > VecField(*Vctrs, float_index);
00262
00263 CurrentDir = VecField.eval();
00264 }
00265 else
00266 {
00267
00268 CurrentFloatIndex = point( tvector( component_wise(component_wise(CurrentVertex - DomainStart, DomainDiagonal, Eagle::Operator<'/'>() ), max_float_index, Eagle::Operator<'*'>()) ));
00269
00270
00271 if(CurrentFloatIndex [0] < 0.0 ||CurrentFloatIndex [0] > max_float_index[0])
00272 break;
00273 if(CurrentFloatIndex [1] < 0.0 ||CurrentFloatIndex [1] > max_float_index[1])
00274 break;
00275 if(CurrentFloatIndex [2] < 0.0 ||CurrentFloatIndex [2] > max_float_index[2])
00276 break;
00277
00278
00279 Interpolate<3, tvector, CubicIpol <tvector> > VecField(*Vctrs, CurrentFloatIndex);
00280 CurrentDir = VecField.eval();
00281 }
00282
00283
00284 CurrentVertex += CurrentDir * hh;
00285 myLine.push_back(CurrentVertex);
00286 embrace( R, CurrentVertex);
00287 }
00288 }
00289
00290 printf("SimpleStreamline::update(): Integrated into Cache\n");
00291 closeBBox( R );
00292
00293 return true;
00294 }
00295
00296
00297 void SimpleStreamline::render( VRenderContext& Context ) const
00298 {
00299
00300
00301 RefPtr<Field> Vectors = getField( Context );
00302 if (!Vectors)
00303 {
00304 puts("void SimpleStreamline::render(VRenderContext&RenderContext): NO VECTORS");
00305 return;
00306 }
00307
00308
00309 const RefPtr<OpCache_t>&OC = OpCache_t::retrieve( *Vectors ) ( self() );
00310 if (!OC)
00311 {
00312 puts("void SimpleStreamline::render(VRenderContext&RenderContext): NO LINE CACHE");
00313 return;
00314 }
00315 if (OC->size()<1)
00316 {
00317 puts("void SimpleStreamline::render(VRenderContext&RenderContext): NO LINES in CACHE");
00318 return;
00319 }
00320
00321 int line_width, point_size;
00322 int line_length = 1;
00323
00324 LineWidth << Context >> line_width;
00325 PointSize << Context >> point_size;
00326 LineLength << Context >> line_length;
00327
00328 if(line_width < 1)
00329 line_width = 1;
00330
00331 glEnable(GL_DEPTH_TEST);
00332 glDisable(GL_LIGHTING);
00333
00334 glLineWidth( line_width );
00335
00336 if(point_size > 0)
00337 glPointSize( point_size );
00338 else
00339 glPointSize( 1 );
00340
00341 RefPtr<MyState> state = myState(Context);
00342
00343 RefPtr<ValueSet> RenderParameterSpace = new ValueSet();
00344 RefPtr<DisplayList> DL;
00345 try{
00346 DL = Context(*OC)(this)( RenderParameterSpace );
00347 }
00348 catch(...){}
00349 RefPtr<ValueSet> Changeables = new ValueSet();
00350 Changeables & Context += LineLength, LineNumber, StepSize;
00351
00352 if ( DL && OC->unchanged( Changeables ))
00353 {
00354 printf("SimpleStreamline::render(): Calling List\n");
00355 DL->call();
00356 }
00357 else
00358 {
00359 printf("SimpleStreamline::render(): Rendering List\n");
00360
00361 DL = Context[*OC][this][ RenderParameterSpace ];
00362 if (!DL) throw "SimpleStreamline::render() No Display List!?";
00363
00364 glCompile( *DL )
00365 {
00366 int l = 0;
00367 int p = 0;
00368
00369
00370 for( OpCache_t::const_iterator lbit = OC->begin(); lbit != OC->end(); lbit++ )
00371 {
00372 p = 0;
00373
00374 Line_t::const_iterator lit = lbit->begin();
00375
00376 if (lit == lbit->end() )
00377 break;
00378
00379 glBegin( GL_LINE_STRIP );
00380 bivector dir;
00381
00382 for(; lit != lbit->end();)
00383 {
00384
00385 point P = *lit;
00386 lit++;
00387 if (lit != lbit->end())
00388 dir = (*lit - P).unit();
00389
00390
00391 glColor3f((double)p/lbit->size() , 1-(double)p/lbit->size(), 0.0);
00392 glVertex( P );
00393
00394 p++;
00395 }
00396
00397 l++;
00398 glEnd();
00399 }
00400
00401
00402
00403 if(point_size > 0 )
00404 {
00405 for( OpCache_t::const_iterator lbit = OC->begin(); lbit != OC->end(); lbit++ )
00406 {
00407 p = 0;
00408
00409 Line_t::const_iterator lit = lbit->begin();
00410
00411 if (lit == lbit->end() )
00412 break;
00413
00414 tvector dir;
00415 glBegin(GL_POINTS);
00416
00417 for(; lit != lbit->end();)
00418 {
00419
00420 point P = *lit;
00421 lit++;
00422 if (lit != lbit->end())
00423 dir = (*lit - P).unit();
00424
00425 glColor3f((double)p/lbit->size(), 1-(double)p/lbit->size(), 0.7);
00426 glVertex( P );
00427
00428 p++;
00429 }
00430 glEnd();
00431 }
00432 }
00433 }
00434 }
00435
00436 state->touch();
00437 }
00438
00439
00440 static Ref<VCreator<SimpleStreamline, AcceptList<Fiber::Field> > > myCreator("Tutorial/SimpleStreamline");
00441
00442 VISH_DEFAULT_INIT