source: branches/nanovis2/packages/vizservers/nanovis/FlowCmd.h @ 3351

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

sync with trunk

  • Property svn:eol-style set to native
File size: 10.3 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-2012  HUBzero Foundation, LLC
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->textureID(),
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 ambient;     ///< Ambient volume shading
210    float diffuse;     ///< Diffuse volume shading
211    float specular;    ///< Specular level volume shading
212    float specularExp; ///< Specular exponent volume shading
213    float opacity;     ///< Volume opacity scaling
214};
215
216struct FlowIterator {
217    Tcl_HashEntry *hashPtr;
218    Tcl_HashSearch hashSearch;
219};
220
221class FlowCmd
222{
223public:
224    enum SliceAxis { AXIS_X, AXIS_Y, AXIS_Z };
225
226    FlowCmd(Tcl_Interp *interp, const char *name, Tcl_HashEntry *hPtr);
227
228    ~FlowCmd();
229
230    int CreateParticles(Tcl_Interp *interp, Tcl_Obj *objPtr);
231
232    int GetParticles(Tcl_Interp *interp, Tcl_Obj *objPtr,
233                     FlowParticles **particlePtrPtr);
234
235    void Render();
236
237    void Advect();
238
239    void ResetParticles();
240
241    void InitializeParticles();
242
243    FlowParticles *FirstParticles(FlowParticlesIterator *iterPtr);
244
245    FlowParticles *NextParticles(FlowParticlesIterator *iterPtr);
246
247    int CreateBox(Tcl_Interp *interp, Tcl_Obj *objPtr);
248
249    int GetBox(Tcl_Interp *interp, Tcl_Obj *objPtr, FlowBox **boxPtrPtr);
250
251    FlowBox *FirstBox(FlowBoxIterator *iterPtr);
252
253    FlowBox *NextBox(FlowBoxIterator *iterPtr);
254
255    float *GetScaledVector();
256
257    Volume *MakeVolume(float *data);
258   
259    void InitVectorField();
260
261    NvVectorField *VectorField()
262    {
263        return _fieldPtr;
264    }
265
266    bool ScaleVectorField();
267
268    bool visible()
269    {
270        return !_sv.isHidden;
271    }
272
273    const char *name()
274    {
275        return _name;
276    }
277
278    void disconnect()
279    {
280        _hashPtr = NULL;
281    }
282
283    bool isDataLoaded()
284    {
285        return (_dataPtr != NULL);
286    }
287
288    Rappture::Unirect3d *data()
289    {
290        return _dataPtr;
291    }
292
293    void data(Rappture::Unirect3d *dataPtr)
294    {
295        if (_dataPtr != NULL) {
296            delete _dataPtr;
297        }
298        _dataPtr = dataPtr;
299    }
300
301    void ActivateSlice()
302    {
303        /* Must set axis before offset or position goes to wrong axis. */
304        NanoVis::licRenderer->setAxis(_sv.slicePos.axis);
305        NanoVis::licRenderer->setOffset(_sv.slicePos.value);
306        NanoVis::licRenderer->active(true);
307    }
308
309    void DeactivateSlice()
310    {
311        NanoVis::licRenderer->active(false);
312    }
313
314    SliceAxis GetAxis()
315    {
316        return (SliceAxis)_sv.slicePos.axis;
317    }
318
319    TransferFunction *GetTransferFunction()
320    {
321        return _sv.tfPtr;
322    }
323
324    float GetRelativePosition();
325
326    void SetAxis()
327    {
328        NanoVis::licRenderer->setAxis(_sv.slicePos.axis);
329    }
330
331    void SetAxis(FlowCmd::SliceAxis axis)
332    {
333        _sv.slicePos.axis = axis;
334        NanoVis::licRenderer->setAxis(_sv.slicePos.axis);
335    }
336
337    void SetCurrentPosition(float position)
338    {
339        _sv.slicePos.value = position;
340        NanoVis::licRenderer->setOffset(_sv.slicePos.value);
341    }
342
343    void SetCurrentPosition()
344    {
345        NanoVis::licRenderer->setOffset(_sv.slicePos.value);
346    }
347
348    void SetActive(bool state)
349    {
350        _sv.sliceVisible = state;
351        NanoVis::licRenderer->active(state);
352    }
353
354    void SetActive()
355    {
356        NanoVis::licRenderer->active(_sv.sliceVisible);
357    }
358
359    void SetVectorField(NvVectorField *fieldPtr)
360    {
361        DeleteVectorField();
362        _fieldPtr = fieldPtr;
363    }
364
365    void DeleteVectorField()
366    {
367        if (_fieldPtr != NULL) {
368            delete _fieldPtr;
369            _fieldPtr = NULL;
370        }
371    }
372
373    int ParseSwitches(Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
374    {
375        if (Rappture::ParseSwitches(interp, _switches, objc, objv, &_sv,
376                                    SWITCH_DEFAULTS) < 0) {
377            return TCL_ERROR;
378        }
379        return TCL_OK;
380    }
381
382    static float GetRelativePosition(FlowPosition *posPtr);
383
384    static Rappture::SwitchSpec videoSwitches[];
385
386private:
387    void Configure();
388
389    void RenderBoxes();
390
391    Tcl_Interp *_interp;
392    Tcl_HashEntry *_hashPtr;
393    /**
394     * Name of the flow.  This may differ
395     * from the name of the command
396     * associated with the flow, if the
397     * command was renamed. */
398    const char *_name;
399
400    /**
401     * Command associated with the flow.
402     * When the command is deleted, so is
403     * the flow. */
404    Tcl_Command _cmdToken;
405
406    /**
407     * Uniform rectangular data
408     * representing the mesh and vector
409     * field values.  These values are
410     * kept to regenerate the volume
411     * associated with the flow. */
412    Rappture::Unirect3d *_dataPtr;
413
414    /**
415     * The volume associated with the
416     * flow.  This isn't the same thing as
417     * a normal volume displayed. */
418    Volume *_volPtr;
419
420    /**
421     * Vector field generated from the
422     * above volume */
423    NvVectorField *_fieldPtr;
424
425    /**
426     * For each field there can be one or
427     * more particle injection planes
428     * where the particles are injected
429     * into the flow. */
430    Tcl_HashTable _particlesTable;
431
432    /**
433     * A table of boxes.  There maybe
434     * zero or more boxes associated
435     * with each field. */
436    Tcl_HashTable _boxTable;
437
438    FlowValues _sv;
439
440    static Rappture::SwitchSpec _switches[];
441};
442
443extern int GetDataStream(Tcl_Interp *interp, Rappture::Buffer &buf, int nBytes);
444
445extern int GetBooleanFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
446                             bool *boolPtr);
447
448extern int GetFloatFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
449                           float *floatPtr);
450
451extern int GetAxisFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
452                          int *axisPtr);
453
454extern int GetVolumeFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
455                            Volume **volumePtrPtr);
456
457#endif
Note: See TracBrowser for help on using the repository browser.