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

Last change on this file since 3492 was 3492, checked in by ldelgass, 6 years ago

Fix camera reset for nanovis. Includes refactoring of vector/matrix classes
in nanovis to consolidate into vrmath library. Also add preliminary canonical
view control to clients for testing.

  • Property svn:eol-style set to native
File size: 10.6 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 <vrmath/Vector3f.h>
30
31#include "Switch.h"
32#include "NvLIC.h"
33#include "NvParticleRenderer.h"
34#include "NvVectorField.h"
35#include "Unirect.h"
36#include "Volume.h"
37
38struct FlowColor {
39    float r, g, b, a;
40};
41
42struct FlowPosition {
43    float value;
44    unsigned int flags;
45    int axis;
46};
47
48struct FlowPoint {
49    float x, y, z;
50};
51
52struct FlowParticlesValues {
53    FlowPosition position;        ///< Position on axis of particle plane
54    FlowColor color;              ///< Color of particles
55    /// Indicates if particle injection plane is active or not
56    int isHidden;
57    float particleSize;           ///< Size of the particles
58};
59
60struct FlowParticlesIterator {
61    Tcl_HashEntry *hashPtr;
62    Tcl_HashSearch hashSearch;
63};
64
65class FlowParticles
66{
67public:
68    FlowParticles(const char *name, Tcl_HashEntry *hPtr);
69
70    ~FlowParticles();
71
72    const char *name()
73    {
74        return _name;
75    }
76
77    void disconnect()
78    {
79        _hashPtr = NULL;
80    }
81
82    bool visible()
83    {
84        return !_sv.isHidden;
85    }
86
87    int parseSwitches(Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
88    {
89        if (Rappture::ParseSwitches(interp, _switches, objc, objv, &_sv, 
90                                    SWITCH_DEFAULTS) < 0) {
91            return TCL_ERROR;
92        }
93        return TCL_OK;
94    }
95
96    void advect()
97    {
98        assert(_rendererPtr->active());
99        _rendererPtr->advect();
100    }
101
102    void render();
103
104    void reset()
105    {
106        _rendererPtr->reset();
107    }
108
109    void initialize()
110    {
111        _rendererPtr->initialize();
112    }
113
114    void setVectorField(Volume *volPtr, const vrmath::Vector3f& location,
115                        float scaleX, float scaleY, float scaleZ,
116                        float max)
117    {
118        _rendererPtr->
119            setVectorField(volPtr->textureID(),
120                           location,
121                           scaleX,
122                           scaleY,
123                           scaleZ,
124                           max);
125    }
126
127    void configure();
128
129private:
130    /**
131     * Name of particle injection plane. Actual character string is
132     * stored in hash table.
133     */
134    const char *_name;
135    Tcl_HashEntry *_hashPtr;
136    NvParticleRenderer *_rendererPtr;        ///< Particle renderer
137    FlowParticlesValues _sv;
138
139    static Rappture::SwitchSpec _switches[];
140};
141
142struct FlowBoxIterator {
143    Tcl_HashEntry *hashPtr;
144    Tcl_HashSearch hashSearch;
145};
146
147struct FlowBoxValues {
148    FlowPoint corner1, corner2;    ///< Coordinates of the box.
149    FlowColor color;               ///< Color of box
150    float lineWidth;
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
193    const FlowBoxValues *getValues() const
194    {
195        return &_sv;
196    }
197
198    void getWorldSpaceBounds(vrmath::Vector3f& min,
199                             vrmath::Vector3f& max,
200                             const Volume *vol) const;
201
202private:
203    const char *_name;          ///< Name of this box in the hash table.
204    Tcl_HashEntry *_hashPtr;    ///< Pointer to this entry in the hash table of boxes.
205    FlowBoxValues _sv;
206    static Rappture::SwitchSpec _switches[];
207
208};
209
210struct FlowValues {
211    TransferFunction *tfPtr;
212    FlowPosition slicePos;
213    int showArrows;
214    int sliceVisible;
215    int showVolume;
216    int showOutline;
217    int isHidden;
218    int twoSidedLighting;
219    float ambient;     ///< Ambient volume shading
220    float diffuse;     ///< Diffuse volume shading
221    float specular;    ///< Specular level volume shading
222    float specularExp; ///< Specular exponent volume shading
223    float opacity;     ///< Volume opacity scaling
224};
225
226struct FlowIterator {
227    Tcl_HashEntry *hashPtr;
228    Tcl_HashSearch hashSearch;
229};
230
231class FlowCmd
232{
233public:
234    enum SliceAxis { AXIS_X, AXIS_Y, AXIS_Z };
235
236    FlowCmd(Tcl_Interp *interp, const char *name, Tcl_HashEntry *hPtr);
237
238    ~FlowCmd();
239
240    int CreateParticles(Tcl_Interp *interp, Tcl_Obj *objPtr);
241
242    int GetParticles(Tcl_Interp *interp, Tcl_Obj *objPtr,
243                     FlowParticles **particlePtrPtr);
244
245    void Render();
246
247    void Advect();
248
249    void ResetParticles();
250
251    void InitializeParticles();
252
253    FlowParticles *FirstParticles(FlowParticlesIterator *iterPtr);
254
255    FlowParticles *NextParticles(FlowParticlesIterator *iterPtr);
256
257    int CreateBox(Tcl_Interp *interp, Tcl_Obj *objPtr);
258
259    int GetBox(Tcl_Interp *interp, Tcl_Obj *objPtr, FlowBox **boxPtrPtr);
260
261    FlowBox *FirstBox(FlowBoxIterator *iterPtr);
262
263    FlowBox *NextBox(FlowBoxIterator *iterPtr);
264
265    float *GetScaledVector();
266
267    Volume *MakeVolume(float *data);
268   
269    void InitVectorField();
270
271    NvVectorField *VectorField()
272    {
273        return _fieldPtr;
274    }
275
276    bool ScaleVectorField();
277
278    bool visible()
279    {
280        return !_sv.isHidden;
281    }
282
283    const char *name()
284    {
285        return _name;
286    }
287
288    void disconnect()
289    {
290        _hashPtr = NULL;
291    }
292
293    bool isDataLoaded()
294    {
295        return (_dataPtr != NULL);
296    }
297
298    Rappture::Unirect3d *data()
299    {
300        return _dataPtr;
301    }
302
303    void data(Rappture::Unirect3d *dataPtr)
304    {
305        if (_dataPtr != NULL) {
306            delete _dataPtr;
307        }
308        _dataPtr = dataPtr;
309    }
310
311    void ActivateSlice()
312    {
313        /* Must set axis before offset or position goes to wrong axis. */
314        NanoVis::licRenderer->setAxis(_sv.slicePos.axis);
315        NanoVis::licRenderer->setOffset(_sv.slicePos.value);
316        NanoVis::licRenderer->active(true);
317    }
318
319    void DeactivateSlice()
320    {
321        NanoVis::licRenderer->active(false);
322    }
323
324    SliceAxis GetAxis()
325    {
326        return (SliceAxis)_sv.slicePos.axis;
327    }
328
329    TransferFunction *GetTransferFunction()
330    {
331        return _sv.tfPtr;
332    }
333
334    float GetRelativePosition();
335
336    void SetAxis()
337    {
338        NanoVis::licRenderer->setAxis(_sv.slicePos.axis);
339    }
340
341    void SetAxis(FlowCmd::SliceAxis axis)
342    {
343        _sv.slicePos.axis = axis;
344        NanoVis::licRenderer->setAxis(_sv.slicePos.axis);
345    }
346
347    void SetCurrentPosition(float position)
348    {
349        _sv.slicePos.value = position;
350        NanoVis::licRenderer->setOffset(_sv.slicePos.value);
351    }
352
353    void SetCurrentPosition()
354    {
355        NanoVis::licRenderer->setOffset(_sv.slicePos.value);
356    }
357
358    void SetActive(bool state)
359    {
360        _sv.sliceVisible = state;
361        NanoVis::licRenderer->active(state);
362    }
363
364    void SetActive()
365    {
366        NanoVis::licRenderer->active(_sv.sliceVisible);
367    }
368
369    void SetVectorField(NvVectorField *fieldPtr)
370    {
371        DeleteVectorField();
372        _fieldPtr = fieldPtr;
373    }
374
375    void DeleteVectorField()
376    {
377        if (_fieldPtr != NULL) {
378            delete _fieldPtr;
379            _fieldPtr = NULL;
380        }
381    }
382
383    int ParseSwitches(Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
384    {
385        if (Rappture::ParseSwitches(interp, _switches, objc, objv, &_sv,
386                                    SWITCH_DEFAULTS) < 0) {
387            return TCL_ERROR;
388        }
389        return TCL_OK;
390    }
391
392    const Volume *getVolume() const
393    {
394        return _volPtr;
395    }
396
397    static float GetRelativePosition(FlowPosition *posPtr);
398
399    static Rappture::SwitchSpec videoSwitches[];
400
401private:
402    void Configure();
403
404    void RenderBoxes();
405
406    Tcl_Interp *_interp;
407    Tcl_HashEntry *_hashPtr;
408    /**
409     * Name of the flow.  This may differ
410     * from the name of the command
411     * associated with the flow, if the
412     * command was renamed. */
413    const char *_name;
414
415    /**
416     * Command associated with the flow.
417     * When the command is deleted, so is
418     * the flow. */
419    Tcl_Command _cmdToken;
420
421    /**
422     * Uniform rectangular data
423     * representing the mesh and vector
424     * field values.  These values are
425     * kept to regenerate the volume
426     * associated with the flow. */
427    Rappture::Unirect3d *_dataPtr;
428
429    /**
430     * The volume associated with the
431     * flow.  This isn't the same thing as
432     * a normal volume displayed. */
433    Volume *_volPtr;
434
435    /**
436     * Vector field generated from the
437     * above volume */
438    NvVectorField *_fieldPtr;
439
440    /**
441     * For each field there can be one or
442     * more particle injection planes
443     * where the particles are injected
444     * into the flow. */
445    Tcl_HashTable _particlesTable;
446
447    /**
448     * A table of boxes.  There maybe
449     * zero or more boxes associated
450     * with each field. */
451    Tcl_HashTable _boxTable;
452
453    FlowValues _sv;
454
455    static Rappture::SwitchSpec _switches[];
456};
457
458extern int GetDataStream(Tcl_Interp *interp, Rappture::Buffer &buf, int nBytes);
459
460extern int GetBooleanFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
461                             bool *boolPtr);
462
463extern int GetFloatFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
464                           float *floatPtr);
465
466extern int GetAxisFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
467                          int *axisPtr);
468
469extern int GetVolumeFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
470                            Volume **volumePtrPtr);
471
472#endif
Note: See TracBrowser for help on using the repository browser.