source: branches/blt4/packages/vizservers/nanovis/FlowCmd.h @ 3061

Last change on this file since 3061 was 3061, checked in by gah, 12 years ago
File size: 10.2 KB
Line 
1/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2/*
3 * ----------------------------------------------------------------------
4 * FlowCmd.h
5 *
6 *      This modules creates the Tcl interface to the nanovis server.  The
7 *      communication protocol of the server is the Tcl language.  Commands
8 *      given to the server by clients are executed in a safe interpreter and
9 *      the resulting image rendered offscreen is returned as BMP-formatted
10 *      image data.
11 *
12 * ======================================================================
13 *  AUTHOR:  Wei Qiao <qiaow@purdue.edu>
14 *           Insoo Woo <iwoo@purdue.edu>
15 *           Michael McLennan <mmclennan@purdue.edu>
16 *           Purdue Rendering and Perceptualization Lab (PURPL)
17 *
18 *  Copyright (c) 2004-2006  Purdue Research Foundation
19 *
20 *  See the file "license.terms" for information on usage and
21 *  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
22 * ======================================================================
23 */
24#ifndef FLOWCMD_H
25#define FLOWCMD_H
26
27#include <tcl.h>
28
29#include "Switch.h"
30#include "NvLIC.h"
31#include "NvParticleRenderer.h"
32#include "NvVectorField.h"
33#include "Unirect.h"
34#include "Volume.h"
35
36struct FlowColor {
37    float r, g, b, a;
38};
39
40struct FlowPosition {
41    float value;
42    unsigned int flags;
43    int axis;
44};
45
46struct FlowPoint {
47    float x, y, z;
48};
49
50struct FlowParticlesValues {
51    FlowPosition position;        ///< Position on axis of particle plane
52    FlowColor color;              ///< Color of particles
53    /// Indicates if particle injection plane is active or not
54    int isHidden;
55    float particleSize;           ///< Size of the particles
56};
57
58struct FlowParticlesIterator {
59    Tcl_HashEntry *hashPtr;
60    Tcl_HashSearch hashSearch;
61};
62
63class FlowParticles
64{
65public:
66    FlowParticles(const char *name, Tcl_HashEntry *hPtr);
67
68    ~FlowParticles();
69
70    const char *name()
71    {
72        return _name;
73    }
74
75    void disconnect()
76    {
77        _hashPtr = NULL;
78    }
79
80    bool visible()
81    {
82        return !_sv.isHidden;
83    }
84
85    int parseSwitches(Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
86    {
87        if (Rappture::ParseSwitches(interp, _switches, objc, objv, &_sv,
88                                    SWITCH_DEFAULTS) < 0) {
89            return TCL_ERROR;
90        }
91        return TCL_OK;
92    }
93
94    void advect()
95    {
96        assert(_rendererPtr->active());
97        _rendererPtr->advect();
98    }
99
100    void render();
101
102    void reset()
103    {
104        _rendererPtr->reset();
105    }
106
107    void initialize()
108    {
109        _rendererPtr->initialize();
110    }
111
112    void setVectorField(Volume *volPtr, const Vector3& location,
113                        float scaleX, float scaleY, float scaleZ,
114                        float max)
115    {
116        _rendererPtr->
117            setVectorField(volPtr->id,
118                           location,
119                           scaleX,
120                           scaleY,
121                           scaleZ,
122                           max);
123    }
124
125    void configure();
126
127private:
128    /**
129     * Name of particle injection plane. Actual character string is
130     * stored in hash table.
131     */
132    const char *_name;
133    Tcl_HashEntry *_hashPtr;
134    NvParticleRenderer *_rendererPtr;        ///< Particle renderer
135    FlowParticlesValues _sv;
136
137    static Rappture::SwitchSpec _switches[];
138};
139
140struct FlowBoxIterator {
141    Tcl_HashEntry *hashPtr;
142    Tcl_HashSearch hashSearch;
143};
144
145struct FlowBoxValues {
146    float position;                ///< Position on axis of particle plane
147    FlowPoint corner1, corner2;    ///< Coordinates of the box.
148    FlowColor color;               ///< Color of particles
149    float lineWidth;
150    /// Indicates if particle injection plane is active or not
151    int isHidden;
152};
153
154class FlowBox
155{
156public:
157    FlowBox(const char *name, Tcl_HashEntry *hPtr);
158
159    ~FlowBox()
160    {
161        Rappture::FreeSwitches(_switches, &_sv, 0);
162        if (_hashPtr != NULL) {
163            Tcl_DeleteHashEntry(_hashPtr);
164        }
165    }
166
167    const char *name()
168    {
169        return _name;
170    }
171
172    bool visible()
173    {
174        return !_sv.isHidden;
175    }
176
177    void disconnect()
178    {
179        _hashPtr = NULL;
180    }
181
182    int ParseSwitches(Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
183    {
184        if (Rappture::ParseSwitches(interp, _switches, objc, objv, &_sv,
185                                    SWITCH_DEFAULTS) < 0) {
186            return TCL_ERROR;
187        }
188        return TCL_OK;
189    }
190
191    void Render(Volume *volPtr);
192
193private:
194    const char *_name;          ///< Name of this box in the hash table.
195    Tcl_HashEntry *_hashPtr;    ///< Pointer to this entry in the hash table of boxes.
196    FlowBoxValues _sv;
197    static Rappture::SwitchSpec _switches[];
198
199};
200
201struct FlowValues {
202    TransferFunction *tfPtr;
203    FlowPosition slicePos;
204    int showArrows;
205    int sliceVisible;
206    int showVolume;
207    int showOutline;
208    int isHidden;
209    float diffuse;  ///< Diffuse volume shading
210    float specular; ///< Specular volume shading
211    float opacity;  ///< Volume opacity
212};
213
214struct FlowIterator {
215    Tcl_HashEntry *hashPtr;
216    Tcl_HashSearch hashSearch;
217};
218
219class FlowCmd
220{
221public:
222    enum SliceAxis { AXIS_X, AXIS_Y, AXIS_Z };
223
224    FlowCmd(Tcl_Interp *interp, const char *name, Tcl_HashEntry *hPtr);
225
226    ~FlowCmd();
227
228    int CreateParticles(Tcl_Interp *interp, Tcl_Obj *objPtr);
229
230    int GetParticles(Tcl_Interp *interp, Tcl_Obj *objPtr,
231                     FlowParticles **particlePtrPtr);
232
233    void Render();
234
235    void Advect();
236
237    void ResetParticles();
238
239    void InitializeParticles();
240
241    FlowParticles *FirstParticles(FlowParticlesIterator *iterPtr);
242
243    FlowParticles *NextParticles(FlowParticlesIterator *iterPtr);
244
245    int CreateBox(Tcl_Interp *interp, Tcl_Obj *objPtr);
246
247    int GetBox(Tcl_Interp *interp, Tcl_Obj *objPtr, FlowBox **boxPtrPtr);
248
249    FlowBox *FirstBox(FlowBoxIterator *iterPtr);
250
251    FlowBox *NextBox(FlowBoxIterator *iterPtr);
252
253    float *GetScaledVector();
254
255    Volume *MakeVolume(float *data);
256   
257    void InitVectorField();
258
259    NvVectorField *VectorField()
260    {
261        return _fieldPtr;
262    }
263
264    bool ScaleVectorField();
265
266    bool visible()
267    {
268        return !_sv.isHidden;
269    }
270
271    const char *name()
272    {
273        return _name;
274    }
275
276    void disconnect()
277    {
278        _hashPtr = NULL;
279    }
280
281    bool isDataLoaded()
282    {
283        return (_dataPtr != NULL);
284    }
285
286    Rappture::Unirect3d *data()
287    {
288        return _dataPtr;
289    }
290
291    void data(Rappture::Unirect3d *dataPtr)
292    {
293        if (_dataPtr != NULL) {
294            delete _dataPtr;
295        }
296        _dataPtr = dataPtr;
297    }
298
299    void ActivateSlice()
300    {
301        /* Must set axis before offset or position goes to wrong axis. */
302        NanoVis::licRenderer->setAxis(_sv.slicePos.axis);
303        NanoVis::licRenderer->setOffset(_sv.slicePos.value);
304        NanoVis::licRenderer->active(true);
305    }
306
307    void DeactivateSlice()
308    {
309        NanoVis::licRenderer->active(false);
310    }
311
312    SliceAxis GetAxis()
313    {
314        return (SliceAxis)_sv.slicePos.axis;
315    }
316
317    TransferFunction *GetTransferFunction()
318    {
319        return _sv.tfPtr;
320    }
321
322    float GetRelativePosition();
323
324    void SetAxis()
325    {
326        NanoVis::licRenderer->setAxis(_sv.slicePos.axis);
327    }
328
329    void SetAxis(FlowCmd::SliceAxis axis)
330    {
331        _sv.slicePos.axis = axis;
332        NanoVis::licRenderer->setAxis(_sv.slicePos.axis);
333    }
334
335    void SetCurrentPosition(float position)
336    {
337        _sv.slicePos.value = position;
338        NanoVis::licRenderer->setOffset(_sv.slicePos.value);
339    }
340
341    void SetCurrentPosition()
342    {
343        NanoVis::licRenderer->setOffset(_sv.slicePos.value);
344    }
345
346    void SetActive(bool state)
347    {
348        _sv.sliceVisible = state;
349        NanoVis::licRenderer->active(state);
350    }
351
352    void SetActive()
353    {
354        NanoVis::licRenderer->active(_sv.sliceVisible);
355    }
356
357    void SetVectorField(NvVectorField *fieldPtr)
358    {
359        DeleteVectorField();
360        _fieldPtr = fieldPtr;
361    }
362
363    void DeleteVectorField()
364    {
365        if (_fieldPtr != NULL) {
366            delete _fieldPtr;
367            _fieldPtr = NULL;
368        }
369    }
370
371    int ParseSwitches(Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
372    {
373        if (Rappture::ParseSwitches(interp, _switches, objc, objv, &_sv,
374                                    SWITCH_DEFAULTS) < 0) {
375            return TCL_ERROR;
376        }
377        return TCL_OK;
378    }
379
380    static float GetRelativePosition(FlowPosition *posPtr);
381
382    static Rappture::SwitchSpec videoSwitches[];
383
384private:
385    void Configure();
386
387    void RenderBoxes();
388
389    Tcl_Interp *_interp;
390    Tcl_HashEntry *_hashPtr;
391    /**
392     * Name of the flow.  This may differ
393     * from the name of the command
394     * associated with the flow, if the
395     * command was renamed. */
396    const char *_name;
397
398    /**
399     * Command associated with the flow.
400     * When the command is deleted, so is
401     * the flow. */
402    Tcl_Command _cmdToken;
403
404    /**
405     * Uniform rectangular data
406     * representing the mesh and vector
407     * field values.  These values are
408     * kept to regenerate the volume
409     * associated with the flow. */
410    Rappture::Unirect3d *_dataPtr;
411
412    /**
413     * The volume associated with the
414     * flow.  This isn't the same thing as
415     * a normal volume displayed. */
416    Volume *_volPtr;
417
418    /**
419     * Vector field generated from the
420     * above volume */
421    NvVectorField *_fieldPtr;
422
423    /**
424     * For each field there can be one or
425     * more particle injection planes
426     * where the particles are injected
427     * into the flow. */
428    Tcl_HashTable _particlesTable;
429
430    /**
431     * A table of boxes.  There maybe
432     * zero or more boxes associated
433     * with each field. */
434    Tcl_HashTable _boxTable;
435
436    FlowValues _sv;
437
438    static Rappture::SwitchSpec _switches[];
439};
440
441extern int GetDataStream(Tcl_Interp *interp, Rappture::Buffer &buf, int nBytes);
442
443extern int GetBooleanFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
444                             bool *boolPtr);
445
446extern int GetFloatFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
447                           float *floatPtr);
448
449extern int GetAxisFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
450                          int *axisPtr);
451
452extern int GetVolumeFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
453                            Volume **volumePtrPtr);
454
455#endif
Note: See TracBrowser for help on using the repository browser.