source: nanovis/branches/1.1/FlowCmd.h @ 4599

Last change on this file since 4599 was 3567, checked in by ldelgass, 11 years ago

Refactor and cleanups in nanovis, mainly to switch to using STL hash tables
(TR1 required) instead of Tcl hash tables, split out Flow particles and boxes
to separate implementation files. The goal is to achieve better separation of
Tcl command parsing and the core graphics rendering objects and code.

  • Property svn:eol-style set to native
File size: 7.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-2013  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 <tr1/unordered_map>
28#include <vector>
29#include <string>
30
31#include <tcl.h>
32
33#include <vrmath/Vector3f.h>
34
35#include "Switch.h"
36#include "FlowTypes.h"
37#include "FlowParticles.h"
38#include "FlowBox.h"
39#include "NvLIC.h"
40#include "NvParticleRenderer.h"
41#include "NvVectorField.h"
42#include "Unirect.h"
43#include "Volume.h"
44#include "TransferFunction.h"
45
46struct FlowValues {
47    TransferFunction *transferFunction;
48    FlowPosition slicePos;
49    int showArrows;
50    int sliceVisible;
51    int showVolume;
52    int showOutline;
53    int isHidden;
54    int twoSidedLighting;
55    float ambient;     ///< Ambient volume shading
56    float diffuse;     ///< Diffuse volume shading
57    float specular;    ///< Specular level volume shading
58    float specularExp; ///< Specular exponent volume shading
59    float opacity;     ///< Volume opacity scaling
60};
61
62class FlowCmd
63{
64public:
65    enum SliceAxis { AXIS_X, AXIS_Y, AXIS_Z };
66
67    FlowCmd(Tcl_Interp *interp, const char *name);
68
69    ~FlowCmd();
70
71    void getBounds(vrmath::Vector3f& min,
72                   vrmath::Vector3f& max,
73                   bool onlyVisible);
74
75    FlowParticles *createParticles(const char *particlesName);
76
77    FlowParticles *getParticles(const char *particlesName);
78
79    void deleteParticles(const char *particlesName);
80
81    void getParticlesNames(std::vector<std::string>& names);
82
83    void render();
84
85    void advect();
86
87    void resetParticles();
88
89    void initializeParticles();
90
91    FlowBox *createBox(const char *boxName);
92
93    FlowBox *getBox(const char *boxName);
94
95    void deleteBox(const char *boxName);
96
97    void getBoxNames(std::vector<std::string>& names);
98
99    float *getScaledVector();
100
101    Volume *makeVolume(float *data);
102   
103    void initVectorField();
104
105    NvVectorField *getVectorField()
106    {
107        return _field;
108    }
109
110    bool scaleVectorField();
111
112    bool visible()
113    {
114        return !_sv.isHidden;
115    }
116
117    const char *name() const
118    {
119        return _name.c_str();
120    }
121
122    bool isDataLoaded()
123    {
124        return (_data != NULL);
125    }
126
127    Rappture::Unirect3d *data()
128    {
129        return _data;
130    }
131
132    void data(Rappture::Unirect3d *data)
133    {
134        if (_data != NULL) {
135            delete _data;
136        }
137        _data = data;
138    }
139
140    void activateSlice()
141    {
142        /* Must set axis before offset or position goes to wrong axis. */
143        NanoVis::licRenderer->setAxis(_sv.slicePos.axis);
144        NanoVis::licRenderer->setOffset(_sv.slicePos.value);
145        NanoVis::licRenderer->active(true);
146    }
147
148    void ceactivateSlice()
149    {
150        NanoVis::licRenderer->active(false);
151    }
152
153    SliceAxis getAxis()
154    {
155        return (SliceAxis)_sv.slicePos.axis;
156    }
157
158    TransferFunction *getTransferFunction()
159    {
160        return _sv.transferFunction;
161    }
162
163    float getRelativePosition();
164
165    void setAxis()
166    {
167        NanoVis::licRenderer->setAxis(_sv.slicePos.axis);
168    }
169
170    void setAxis(FlowCmd::SliceAxis axis)
171    {
172        _sv.slicePos.axis = axis;
173        NanoVis::licRenderer->setAxis(_sv.slicePos.axis);
174    }
175
176    void setCurrentPosition(float position)
177    {
178        _sv.slicePos.value = position;
179        NanoVis::licRenderer->setOffset(_sv.slicePos.value);
180    }
181
182    void setCurrentPosition()
183    {
184        NanoVis::licRenderer->setOffset(_sv.slicePos.value);
185    }
186
187    void setActive(bool state)
188    {
189        _sv.sliceVisible = state;
190        NanoVis::licRenderer->active(state);
191    }
192
193    void setActive()
194    {
195        NanoVis::licRenderer->active(_sv.sliceVisible);
196    }
197
198    void setVectorField(NvVectorField *field)
199    {
200        deleteVectorField();
201        _field = field;
202    }
203
204    void deleteVectorField()
205    {
206        if (_field != NULL) {
207            delete _field;
208            _field = NULL;
209        }
210    }
211
212    const Volume *getVolume() const
213    {
214        return _volume;
215    }
216
217    int parseSwitches(Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
218    {
219        if (Rappture::ParseSwitches(interp, _switches, objc, objv, &_sv,
220                                    SWITCH_DEFAULTS) < 0) {
221            return TCL_ERROR;
222        }
223        return TCL_OK;
224    }
225
226    Tcl_Command getCommandToken()
227    {
228        return _cmdToken;
229    }
230
231    static float getRelativePosition(FlowPosition *pos);
232
233    static Rappture::SwitchSpec videoSwitches[];
234
235private:
236    typedef std::string ParticlesId;
237    typedef std::string BoxId;
238    typedef std::tr1::unordered_map<ParticlesId, FlowParticles *> ParticlesHashmap;
239    typedef std::tr1::unordered_map<BoxId, FlowBox *> BoxHashmap;
240
241    void configure();
242
243    void renderBoxes();
244
245    Tcl_Interp *_interp;
246    /**
247     * Name of the flow.  This may differ
248     * from the name of the command
249     * associated with the flow, if the
250     * command was renamed. */
251    std::string _name;
252
253    /**
254     * Command associated with the flow.
255     * When the command is deleted, so is
256     * the flow. */
257    Tcl_Command _cmdToken;
258
259    /**
260     * Uniform rectangular data
261     * representing the mesh and vector
262     * field values.  These values are
263     * kept to regenerate the volume
264     * associated with the flow. */
265    Rappture::Unirect3d *_data;
266
267    /**
268     * The volume associated with the
269     * flow.  This isn't the same thing as
270     * a normal volume displayed. */
271    Volume *_volume;
272
273    /**
274     * Vector field generated from the
275     * above volume */
276    NvVectorField *_field;
277
278    /**
279     * For each field there can be one or
280     * more particle injection planes
281     * where the particles are injected
282     * into the flow. */
283    ParticlesHashmap _particlesTable;
284
285    /**
286     * A table of boxes.  There maybe
287     * zero or more boxes associated
288     * with each field. */
289    BoxHashmap _boxTable;
290
291    FlowValues _sv;
292
293    static Rappture::SwitchSpec _switches[];
294};
295
296extern int GetDataStream(Tcl_Interp *interp, Rappture::Buffer &buf, int nBytes);
297
298extern int GetBooleanFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
299                             bool *boolVal);
300
301extern int GetFloatFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
302                           float *floatVal);
303
304extern int GetAxisFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
305                          int *axisVal);
306
307extern int GetVolumeFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
308                            Volume **volume);
309
310#endif
Note: See TracBrowser for help on using the repository browser.