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

Last change on this file since 2875 was 2875, checked in by ldelgass, 13 years ago

Don't use memset on this pointer -- will blow up if virtual methods are added.
Also formatting cleanups.

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