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

Last change on this file since 2844 was 2844, checked in by ldelgass, 12 years ago

Cleanups, no functional changes

  • Property svn:eol-style set to native
File size: 10.1 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)
113    {
114        _rendererPtr->
115            setVectorField(volPtr->id,
116                           volPtr->location(),
117                           1.0f,
118                           volPtr->height / (float)volPtr->width,
119                           volPtr->depth  / (float)volPtr->width,
120                           volPtr->wAxis.max());
121    }
122
123    void Configure();
124
125private:
126    /**
127     * Name of particle injection plane. Actual character string is
128     * stored in hash table.
129     */
130    const char *_name;
131    Tcl_HashEntry *_hashPtr;
132    NvParticleRenderer *_rendererPtr;   ///< Particle renderer
133    FlowParticlesValues _sv;
134
135    static Rappture::SwitchSpec _switches[];
136};
137
138struct FlowBoxIterator {
139    Tcl_HashEntry *hashPtr;
140    Tcl_HashSearch hashSearch;
141};
142
143struct FlowBoxValues {
144    float position;             ///< Position on axis of particle plane
145    FlowPoint corner1, corner2; ///< Coordinates of the box.
146    FlowColor color;            ///< Color of particles
147    float lineWidth;
148    /// Indicates if particle injection plane is active or not
149    int isHidden;
150};
151
152class FlowBox
153{
154public:
155    FlowBox(const char *name, Tcl_HashEntry *hPtr);
156
157    ~FlowBox()
158    {
159        Rappture::FreeSwitches(_switches, &_sv, 0);
160        if (_hashPtr != NULL) {
161            Tcl_DeleteHashEntry(_hashPtr);
162        }
163    }
164
165    const char *name()
166    {
167        return _name;
168    }
169
170    bool visible()
171    {
172        return !_sv.isHidden;
173    }
174
175    void disconnect()
176    {
177        _hashPtr = NULL;
178    }
179
180    int ParseSwitches(Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
181    {
182        if (Rappture::ParseSwitches(interp, _switches, objc, objv, &_sv,
183                                    SWITCH_DEFAULTS) < 0) {
184            return TCL_ERROR;
185        }
186        return TCL_OK;
187    }
188
189    void Render(Volume *volPtr);
190
191private:
192    const char *_name;                  /* Name of this box in the hash
193                                         * table. */
194    Tcl_HashEntry *_hashPtr;            /* Pointer to this entry in the hash
195                                         * 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    /* The following are settings for the volume.*/
210    float diffuse;
211    float specular;
212    float opacity;
213};
214
215struct FlowIterator {
216    Tcl_HashEntry *hashPtr;
217    Tcl_HashSearch hashSearch;
218};
219
220class FlowCmd
221{
222public:
223    enum SliceAxis { AXIS_X, AXIS_Y, AXIS_Z };
224
225    FlowCmd(Tcl_Interp *interp, const char *name, Tcl_HashEntry *hPtr);
226
227    ~FlowCmd();
228
229    int CreateParticles(Tcl_Interp *interp, Tcl_Obj *objPtr);
230
231    int GetParticles(Tcl_Interp *interp, Tcl_Obj *objPtr,
232                     FlowParticles **particlePtrPtr);
233
234    void Render();
235
236    void Advect();
237
238    void ResetParticles();
239
240    void InitializeParticles();
241
242    FlowParticles *FirstParticles(FlowParticlesIterator *iterPtr);
243
244    FlowParticles *NextParticles(FlowParticlesIterator *iterPtr);
245
246    int CreateBox(Tcl_Interp *interp, Tcl_Obj *objPtr);
247
248    int GetBox(Tcl_Interp *interp, Tcl_Obj *objPtr, FlowBox **boxPtrPtr);
249
250    FlowBox *FirstBox(FlowBoxIterator *iterPtr);
251
252    FlowBox *NextBox(FlowBoxIterator *iterPtr);
253
254    float *GetScaledVector();
255
256    Volume *MakeVolume(float *data);
257   
258    void InitVectorField();
259
260    NvVectorField *VectorField()
261    {
262        return _fieldPtr;
263    }
264
265    bool ScaleVectorField();
266
267    bool visible()
268    {
269        return !_sv.isHidden;
270    }
271
272    const char *name()
273    {
274        return _name;
275    }
276
277    void disconnect()
278    {
279        _hashPtr = NULL;
280    }
281
282    bool isDataLoaded()
283    {
284        return (_dataPtr != NULL);
285    }
286
287    Rappture::Unirect3d *data()
288    {
289        return _dataPtr;
290    }
291
292    void data(Rappture::Unirect3d *dataPtr)
293    {
294        if (_dataPtr != NULL) {
295            delete _dataPtr;
296        }
297        _dataPtr = dataPtr;
298    }
299
300    void ActivateSlice()
301    {
302        /* Must set axis before offset or position goes to wrong axis. */
303        NanoVis::licRenderer->set_axis(_sv.slicePos.axis);
304        NanoVis::licRenderer->set_offset(_sv.slicePos.value);
305        NanoVis::licRenderer->active(true);
306    }
307
308    void DeactivateSlice()
309    {
310        NanoVis::licRenderer->active(false);
311    }
312
313    SliceAxis GetAxis()
314    {
315        return (SliceAxis)_sv.slicePos.axis;
316    }
317
318    TransferFunction *GetTransferFunction()
319    {
320        return _sv.tfPtr;
321    }
322
323    float GetRelativePosition();
324
325    void SetAxis()
326    {
327        NanoVis::licRenderer->set_axis(_sv.slicePos.axis);
328    }
329
330    void SetAxis(FlowCmd::SliceAxis axis)
331    {
332        _sv.slicePos.axis = axis;
333        NanoVis::licRenderer->set_axis(_sv.slicePos.axis);
334    }
335
336    void SetCurrentPosition(float position)
337    {
338        _sv.slicePos.value = position;
339        NanoVis::licRenderer->set_offset(_sv.slicePos.value);
340    }
341
342    void SetCurrentPosition()
343    {
344        NanoVis::licRenderer->set_offset(_sv.slicePos.value);
345    }
346
347    void SetActive(bool state)
348    {
349        _sv.sliceVisible = state;
350        NanoVis::licRenderer->active(state);
351    }
352
353    void SetActive()
354    {
355        NanoVis::licRenderer->active(_sv.sliceVisible);
356    }
357
358    void SetVectorField(NvVectorField *fieldPtr)
359    {
360        DeleteVectorField();
361        _fieldPtr = fieldPtr;
362    }
363
364    void DeleteVectorField()
365    {
366        if (_fieldPtr != NULL) {
367            delete _fieldPtr;
368            _fieldPtr = NULL;
369        }
370    }
371
372    int ParseSwitches(Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
373    {
374        if (Rappture::ParseSwitches(interp, _switches, objc, objv, &_sv,
375                                    SWITCH_DEFAULTS) < 0) {
376            return TCL_ERROR;
377        }
378        return TCL_OK;
379    }
380
381    static float GetRelativePosition(FlowPosition *posPtr);
382
383    static Rappture::SwitchSpec videoSwitches[];
384
385private:
386    void Configure();
387
388    void RenderBoxes();
389
390    Tcl_Interp *_interp;
391    Tcl_HashEntry *_hashPtr;
392    /**
393     * Name of the flow.  This may differ
394     * from the name of the command
395     * associated with the flow, if the
396     * command was renamed. */
397    const char *_name;
398
399    /**
400     * Command associated with the flow.
401     * When the command is deleted, so is
402     * the flow. */
403    Tcl_Command _cmdToken;
404
405    /**
406     * Uniform rectangular data
407     * representing the mesh and vector
408     * field values.  These values are
409     * kept to regenerate the volume
410     * associated with the flow. */
411    Rappture::Unirect3d *_dataPtr;
412
413    /**
414     * The volume associated with the
415     * flow.  This isn't the same thing as
416     * a normal volume displayed. */
417    Volume *_volPtr;
418
419    /**
420     * Vector field generated from the
421     * above volume */
422    NvVectorField *_fieldPtr;
423
424    /**
425     * For each field there can be one or
426     * more particle injection planes
427     * where the particles are injected
428     * into the flow. */
429    Tcl_HashTable _particlesTable;
430
431    /**
432     * A table of boxes.  There maybe
433     * zero or more boxes associated
434     * with each field. */
435    Tcl_HashTable _boxTable;
436
437    FlowValues _sv;
438
439    static Rappture::SwitchSpec _switches[];
440};
441
442extern int GetDataStream(Tcl_Interp *interp, Rappture::Buffer &buf, int nBytes);
443
444extern int GetBooleanFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
445                             bool *boolPtr);
446
447extern int GetFloatFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
448                           float *floatPtr);
449
450extern int GetAxisFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
451                          int *axisPtr);
452
453extern int GetVolumeFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
454                            Volume **volumePtrPtr);
455
456#endif
Note: See TracBrowser for help on using the repository browser.