source: trunk/packages/vizservers/nanovis/FlowCmd.h @ 1429

Last change on this file since 1429 was 1429, checked in by gah, 15 years ago

Initial commit of new flow visualization command structure

File size: 9.9 KB
Line 
1
2struct FlowColor {
3    float r, g, b, a;
4};
5
6struct FlowPosition {
7    float value;
8    unsigned int flags;
9    int axis;
10};
11
12struct FlowPoint {
13    float x, y, z;
14};
15
16struct FlowParticlesValues {
17    int isHidden;                       /* Indicates if particle injection
18                                         * plance is active or not. */
19    FlowPosition position;              /* Position on axis of particle
20                                         * plane */
21    FlowColor color;                    /* Color of particles */
22};
23
24struct FlowParticlesIterator {
25    Tcl_HashEntry *hashPtr;
26    Tcl_HashSearch hashSearch;
27};
28
29class FlowParticles {
30    const char *_name;                  /* Name of particle injection
31                                         * plane. Actual character string is
32                                         * stored in hash table. */
33    Tcl_HashEntry *_hashPtr;
34    NvParticleRenderer *_rendererPtr;   /* Particle renderer. */
35    FlowParticlesValues _sv;
36
37    static Rappture::SwitchSpec _switches[];
38public:
39
40    FlowParticles(const char *name, Tcl_HashEntry *hPtr);
41    ~FlowParticles(void) {
42        Rappture::FreeSwitches(_switches, &_sv, 0);
43        if (_rendererPtr != NULL) {
44            delete _rendererPtr;
45        }
46        if (_hashPtr != NULL) {
47            Tcl_DeleteHashEntry(_hashPtr);
48        }
49    }
50    void SetColor(FlowColor &color) {
51        _sv.color = color;
52        _rendererPtr->setColor(Vector4(color.r, color.g, color.b, color.a));
53    }
54    const char *name(void) {
55        return _name;
56    }
57    void disconnect(void) {
58        _hashPtr = NULL;
59    }
60    bool visible(void) {
61        return !_sv.isHidden;
62    }
63    int ParseSwitches(Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) {
64        if (Rappture::ParseSwitches(interp, _switches, objc, objv, &_sv,
65                SWITCH_DEFAULTS) < 0) {
66            return TCL_ERROR;
67        }
68        return TCL_OK;
69    }
70    void Advect(void) {
71        assert(_rendererPtr->isActivated());
72        _rendererPtr->advect();
73    }
74    void Render(void);
75    void Reset(void) {
76        _rendererPtr->reset();
77    }
78    void Initialize(void) {
79        _rendererPtr->initialize();
80    }
81    void SetVectorField(Volume *volPtr) {
82        _rendererPtr->setVectorField(volPtr->id,
83            *(volPtr->get_location()),
84            1.0f,
85            volPtr->height / (float)volPtr->width,
86            volPtr->depth  / (float)volPtr->width,
87            volPtr->wAxis.max());
88    }
89    void Configure(void);
90};
91
92struct FlowBoxIterator {
93    Tcl_HashEntry *hashPtr;
94    Tcl_HashSearch hashSearch;
95};
96
97struct FlowBoxValues {
98    int isHidden;                       /* Indicates if particle injection
99                                         * plance is active or not. */
100    float position;                     /* Position on axis of particle
101                                         * plane */
102    FlowPoint corner1, corner2;         /* Coordinates of the box. */
103   
104    FlowColor color;                    /* Color of particles */
105    float lineWidth;
106};
107
108class FlowBox {
109    const char *_name;                  /* Name of this box in the hash
110                                         * table. */
111    Tcl_HashEntry *_hashPtr;            /* Pointer to this entry in the hash
112                                         * table of boxes. */
113    FlowBoxValues _sv;
114    static Rappture::SwitchSpec _switches[];
115public:
116
117    FlowBox(const char *name, Tcl_HashEntry *hPtr);
118    ~FlowBox(void) {
119        Rappture::FreeSwitches(_switches, &_sv, 0);
120        if (_hashPtr != NULL) {
121            Tcl_DeleteHashEntry(_hashPtr);
122        }
123    }
124    const char *name(void) {
125        return _name;
126    }
127    bool visible(void) {
128        return !_sv.isHidden;
129    }
130    void disconnect(void) {
131        _hashPtr = NULL;
132    }
133    int ParseSwitches(Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) {
134        if (Rappture::ParseSwitches(interp, _switches, objc, objv, &_sv,
135                SWITCH_DEFAULTS) < 0) {
136            return TCL_ERROR;
137        }
138        return TCL_OK;
139    }
140    void Render(Volume *volPtr);
141};
142
143struct FlowValues {
144    TransferFunction *tfPtr;
145    FlowPosition slicePos;
146    int sliceVisible;
147    int showVolume;
148    int showOutline;
149    int isHidden;
150};
151
152struct FlowIterator {
153    Tcl_HashEntry *hashPtr;
154    Tcl_HashSearch hashSearch;
155};
156
157class FlowCmd {
158    Tcl_Interp *_interp;
159    Tcl_HashEntry *_hashPtr;
160    const char *_name;                  /* Name of the flow.  This may differ
161                                         * from the name of the command
162                                         * associated with the flow, if the
163                                         * command was renamed. */
164    Tcl_Command _cmdToken;              /* Command associated with the flow.
165                                         * When the command is deleted, so is
166                                         * the flow. */
167    Rappture::Unirect3d *_dataPtr;      /* Uniform rectangular data
168                                         * representing the mesh and vector
169                                         * field values.  These values are
170                                         * kept to regenerate the volume
171                                         * associated with the flow. */
172    Volume *_volPtr;                    /* The volume associated with the
173                                         * flow.  This isn't the same thing as
174                                         * a normal volume displayed. */
175    int _volIndex;                      /* The index of slot in the volume
176                                         * vector. -1 indicates that a slot
177                                         * hasn't been previously allocated.
178                                         * This is to reuse the same slot so
179                                         * the volume vector doesn't grow when
180                                         * we reallocate vectors. */
181
182    NvVectorField *_fieldPtr;           /* Vector field generated from the
183                                         * above volume. */
184
185    Tcl_HashTable _particlesTable;      /* For each field there can be one or
186                                         * more particle injection planes
187                                         * where the particles are injected
188                                         * into the flow. */
189
190    Tcl_HashTable _boxTable;            /* A table of boxes.  The many be
191                                         * zero or more boxes associated
192                                         * with each field. */
193
194    void Configure(void);
195
196    /* Overall ranges over all flow vectors. */
197    static float _xMin, _xMax, _yMin, _yMax, _zMin, _zMax, _wMin, _wMax;
198    static float _magMin, _magMax;
199    static float _xOrigin, _yOrigin, _zOrigin;
200
201    static Rappture::SwitchSpec _switches[];
202    FlowValues _sv;
203
204    /* Class-generic data */
205    static Tcl_HashTable _flowTable;
206    static int _initialized;
207
208    void RenderBoxes(void);
209public:
210    static unsigned int flags;
211    enum SliceAxis { AXIS_X, AXIS_Y, AXIS_Z };
212    enum FlowCmdFlags { REDRAW_PENDING=(1<<0), MAP_PENDING=(1<<1) };
213    FlowCmd(Tcl_Interp *interp, const char *name, Tcl_HashEntry *hPtr);
214    ~FlowCmd(void);
215
216    int CreateParticles(Tcl_Interp *interp, Tcl_Obj *objPtr);
217    int GetParticles(Tcl_Interp *interp, Tcl_Obj *objPtr,
218                     FlowParticles **particlePtrPtr);
219    void Render(void);
220    void Advect(void);
221    void ResetParticles(void);
222    void InitializeParticles(void);
223
224    FlowParticles *FirstParticles(FlowParticlesIterator *iterPtr);
225    FlowParticles *NextParticles(FlowParticlesIterator *iterPtr);
226
227    int CreateBox(Tcl_Interp *interp, Tcl_Obj *objPtr);
228    int GetBox(Tcl_Interp *interp, Tcl_Obj *objPtr, FlowBox **boxPtrPtr);
229    FlowBox *FirstBox(FlowBoxIterator *iterPtr);
230    FlowBox *NextBox(FlowBoxIterator *iterPtr);
231
232    static FlowCmd *FirstFlow(FlowIterator *iterPtr);
233    static FlowCmd *NextFlow(FlowIterator *iterPtr);
234    static void Init(void);
235    static int GetFlow(Tcl_Interp *interp, Tcl_Obj *objPtr,
236                       FlowCmd **flowPtrPtr);
237    static int CreateFlow(Tcl_Interp *interp, Tcl_Obj *objPtr);
238    static void DeleteFlows(Tcl_Interp *interp);
239    static bool MapFlows(void);
240    static void RenderFlows(void);
241    static void ResetFlows(void);
242    static bool UpdateFlows(void);
243    static void AdvectFlows(void);
244
245    float *GetScaledVector(void);
246    Volume *MakeVolume(float *data);
247   
248    void InitVectorField(void);
249
250    NvVectorField *VectorField(void) {
251        return _fieldPtr;
252    }
253
254    bool ScaleVectorField(void);
255
256    bool visible(void) {
257        return !_sv.isHidden;
258    }
259    const char *name(void) {
260        return _name;
261    }
262    void disconnect(void) {
263        _hashPtr = NULL;
264    }
265    bool isDataLoaded(void) {
266        return (_dataPtr != NULL);
267    }
268    Rappture::Unirect3d *GetData(void) {
269        return _dataPtr;
270    }
271    void SetData(Rappture::Unirect3d *dataPtr) {
272        if (_dataPtr != NULL) {
273            delete _dataPtr;
274        }
275        _dataPtr = dataPtr;
276    }
277    void ActivateSlice(void) {
278        /* Must set axis before offset or position goes to wrong axis. */
279        NanoVis::licRenderer->set_axis(_sv.slicePos.axis);
280        NanoVis::licRenderer->set_offset(_sv.slicePos.value);
281        NanoVis::licRenderer->activate();
282    }
283    void DeactivateSlice(void) {
284        NanoVis::licRenderer->deactivate();
285    }
286    SliceAxis GetAxis(void) {
287        return (SliceAxis)_sv.slicePos.axis;
288    }
289    float GetPosition(void);
290    void SetAxis(void) {
291        NanoVis::licRenderer->set_axis(_sv.slicePos.axis);
292    }
293    void SetAxis(FlowCmd::SliceAxis axis) {
294        _sv.slicePos.axis = axis;
295        NanoVis::licRenderer->set_axis(_sv.slicePos.axis);
296    }
297    void SetCurrentPosition(float position) {
298        _sv.slicePos.value = position;
299        NanoVis::licRenderer->set_offset(_sv.slicePos.value);
300    }
301    void SetCurrentPosition(void) {
302        NanoVis::licRenderer->set_offset(_sv.slicePos.value);
303    }
304    void GetMagRange(double &min_mag, double &max_mag);
305
306    void SetVectorField(NvVectorField *fieldPtr) {
307        DeleteVectorField();
308        _fieldPtr = fieldPtr;
309    }
310    void DeleteVectorField(void) {
311        if (_fieldPtr != NULL) {
312            delete _fieldPtr;
313            _fieldPtr = NULL;
314        }
315    }
316    int ParseSwitches(Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) {
317        if (Rappture::ParseSwitches(interp, _switches, objc, objv, &_sv,
318                SWITCH_DEFAULTS) < 0) {
319            return TCL_ERROR;
320        }
321        return TCL_OK;
322    }
323    static void EventuallyRedraw(unsigned int flag = 0) {
324        if (flag) {
325            flags |= flag;
326        }
327        if ((flags & FlowCmd::REDRAW_PENDING) == 0) {
328            glutPostRedisplay();
329            flags |= FlowCmd::REDRAW_PENDING;
330        }
331    }
332    static float GetPosition(FlowPosition *posPtr);
333};
334
335extern int GetDataStream(Tcl_Interp *interp, Rappture::Buffer &buf, int nBytes);
336#ifdef notdef
337extern bool SetVectorFieldData(Rappture::Outcome &context,
338        float xMin, float xMax, size_t xNum,
339        float yMin, float yMax, size_t yNum,
340        float zMin, float zMax, size_t zNum,
341        size_t nValues, float *values,
342        FlowCmd *flowPtr);
343
344extern bool SetResampledVectorFieldData(Rappture::Outcome &context,
345        float xMin, float xMax, size_t xNum,
346        float yMin, float yMax, size_t yNum,
347        float zMin, float zMax, size_t zNum,
348        size_t nValues, float *values,
349        FlowCmd *flowPtr);
350
351extern bool SetVectorFieldDataFromUnirect3d(Rappture::Outcome &context,
352        Rappture::Unirect3d &data, FlowCmd *flowPtr);
353#endif
354
355extern int GetBooleanFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
356        bool *boolPtr);
357extern int GetFloatFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
358        float *floatPtr);
359extern int GetAxisFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
360        int *axisPtr);
361extern int GetVolumeFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
362        Volume **volumePtrPtr);
363
364
Note: See TracBrowser for help on using the repository browser.