source: trunk/packages/vizservers/vtkvis/RendererGraphicsObjs.cpp @ 3696

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

Use imroved Arc API (arc can only represent a circular section, and setting
two endpoints could cause problems with endpts and center colinear and radii
from center to two endpoints differing). New API uses a center, start point,
normal and sweep angle. Also change Line to support polylines: protocol is
changed to require a Tcl list for point coordinates instead of a fixed 2
endpoints.

  • Property svn:eol-style set to native
File size: 91.4 KB
Line 
1/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2/*
3 * Copyright (C) 2004-2012  HUBzero Foundation, LLC
4 *
5 * Author: Leif Delgass <ldelgass@purdue.edu>
6 */
7
8#include <cstring>
9#include <typeinfo>
10#include <vector>
11
12#include <vtkVersion.h>
13#include <vtkSmartPointer.h>
14#include <vtkDataSet.h>
15#include <vtkCharArray.h>
16#include <vtkDataSetReader.h>
17
18#include "RendererGraphicsObjs.h"
19#include "Renderer.h"
20#include "DataSet.h"
21#include "Box.h"
22#include "Contour2D.h"
23#include "Contour3D.h"
24#include "Cutplane.h"
25#include "Glyphs.h"
26#include "HeightMap.h"
27#include "LIC.h"
28#include "Line.h"
29#include "Molecule.h"
30#include "PolyData.h"
31#include "PseudoColor.h"
32#include "Sphere.h"
33#include "Streamlines.h"
34#include "Volume.h"
35#include "ColorMap.h"
36#include "Trace.h"
37
38// Template specializations
39namespace VtkVis {
40
41template<>
42Renderer::ArcHashmap &
43Renderer::getGraphicsObjectHashmap<Arc>()
44{ return _arcs; }
45
46template<>
47Renderer::ArrowHashmap &
48Renderer::getGraphicsObjectHashmap<Arrow>()
49{ return _arrows; }
50
51template<>
52Renderer::BoxHashmap &
53Renderer::getGraphicsObjectHashmap<Box>()
54{ return _boxes; }
55
56template<>
57Renderer::ConeHashmap &
58Renderer::getGraphicsObjectHashmap<Cone>()
59{ return _cones; }
60
61template<>
62Renderer::Contour2DHashmap &
63Renderer::getGraphicsObjectHashmap<Contour2D>()
64{ return _contour2Ds; }
65
66template<>
67Renderer::Contour3DHashmap &
68Renderer::getGraphicsObjectHashmap<Contour3D>()
69{ return _contour3Ds; }
70
71template<>
72Renderer::CutplaneHashmap &
73Renderer::getGraphicsObjectHashmap<Cutplane>()
74{ return _cutplanes; }
75
76template<>
77Renderer::CylinderHashmap &
78Renderer::getGraphicsObjectHashmap<Cylinder>()
79{ return _cylinders; }
80
81template<>
82Renderer::DiskHashmap &
83Renderer::getGraphicsObjectHashmap<Disk>()
84{ return _disks; }
85
86template<>
87Renderer::GlyphsHashmap &
88Renderer::getGraphicsObjectHashmap<Glyphs>()
89{ return _glyphs; }
90
91template<>
92Renderer::GroupHashmap &
93Renderer::getGraphicsObjectHashmap<Group>()
94{ return _groups; }
95
96template<>
97Renderer::HeightMapHashmap &
98Renderer::getGraphicsObjectHashmap<HeightMap>()
99{ return _heightMaps; }
100
101template<>
102Renderer::LICHashmap &
103Renderer::getGraphicsObjectHashmap<LIC>()
104{ return _lics; }
105
106template<>
107Renderer::LineHashmap &
108Renderer::getGraphicsObjectHashmap<Line>()
109{ return _lines; }
110
111template<>
112Renderer::MoleculeHashmap &
113Renderer::getGraphicsObjectHashmap<Molecule>()
114{ return _molecules; }
115
116template<>
117Renderer::OutlineHashmap &
118Renderer::getGraphicsObjectHashmap<Outline>()
119{ return _outlines; }
120
121template<>
122Renderer::PolyDataHashmap &
123Renderer::getGraphicsObjectHashmap<PolyData>()
124{ return _polyDatas; }
125
126template<>
127Renderer::PolygonHashmap &
128Renderer::getGraphicsObjectHashmap<Polygon>()
129{ return _polygons; }
130
131template<>
132Renderer::PseudoColorHashmap &
133Renderer::getGraphicsObjectHashmap<PseudoColor>()
134{ return _pseudoColors; }
135
136template<>
137Renderer::SphereHashmap &
138Renderer::getGraphicsObjectHashmap<Sphere>()
139{ return _spheres; }
140
141template<>
142Renderer::StreamlinesHashmap &
143Renderer::getGraphicsObjectHashmap<Streamlines>()
144{ return _streamlines; }
145
146template<>
147Renderer::VolumeHashmap &
148Renderer::getGraphicsObjectHashmap<Volume>()
149{ return _volumes; }
150
151template<>
152Renderer::WarpHashmap &
153Renderer::getGraphicsObjectHashmap<Warp>()
154{ return _warps; }
155
156template Arc *Renderer::getGraphicsObject(const DataSetId&);
157template Arrow *Renderer::getGraphicsObject(const DataSetId&);
158template Box *Renderer::getGraphicsObject(const DataSetId&);
159template Cone *Renderer::getGraphicsObject(const DataSetId&);
160template Cylinder *Renderer::getGraphicsObject(const DataSetId&);
161template Disk *Renderer::getGraphicsObject(const DataSetId&);
162template Group *Renderer::getGraphicsObject(const DataSetId&);
163template Line *Renderer::getGraphicsObject(const DataSetId&);
164template Polygon *Renderer::getGraphicsObject(const DataSetId&);
165template Sphere *Renderer::getGraphicsObject(const DataSetId&);
166
167template <>
168void Renderer::deleteGraphicsObject<Group>(const DataSetId& id)
169{
170    GroupHashmap& hashmap = getGraphicsObjectHashmap<Group>();
171    GroupHashmap::iterator itr;
172
173    bool doAll = false;
174
175    if (id.compare("all") == 0) {
176        itr = hashmap.begin();
177        doAll = true;
178    } else {
179        itr = hashmap.find(id);
180    }
181    if (itr == hashmap.end()) {
182        ERROR("Group not found: %s", id.c_str());
183        return;
184    }
185
186    TRACE("Deleting Group: %s", id.c_str());
187
188    do {
189        Group *gobj = itr->second;
190        if (gobj->getProp())
191            _renderer->RemoveViewProp(gobj->getProp());
192        if (gobj->getOverlayProp())
193            _renderer->RemoveViewProp(gobj->getOverlayProp());
194
195        std::vector<GraphicsObject *> children;
196        gobj->getChildren(children);
197
198        // Un-grouping children
199        for (std::vector<GraphicsObject *>::iterator citr = children.begin();
200             citr != children.end(); ++citr) {
201            if ((*citr)->getProp())
202                _renderer->AddViewProp((*citr)->getProp());
203            if ((*citr)->getOverlayProp())
204                _renderer->AddViewProp((*citr)->getOverlayProp());
205        }
206
207        delete gobj;
208
209        itr = hashmap.erase(itr);
210    } while (doAll && itr != hashmap.end());
211
212    sceneBoundsChanged();
213    _needsRedraw = true;
214}
215
216template <>
217bool Renderer::addGraphicsObject<Box>(const DataSetId& id)
218{
219    Box *gobj;
220    if ((gobj = getGraphicsObject<Box>(id)) != NULL) {
221        WARN("Replacing existing %s %s", gobj->getClassName(), id.c_str());
222        deleteGraphicsObject<Box>(id);
223    }
224
225    gobj = new Box();
226 
227    gobj->setDataSet(NULL, this);
228
229    if (gobj->getProp() == NULL &&
230        gobj->getOverlayProp() == NULL) {
231        delete gobj;
232        return false;
233    } else {
234        if (gobj->getProp())
235            _renderer->AddViewProp(gobj->getProp());
236        if (gobj->getOverlayProp())
237            _renderer->AddViewProp(gobj->getOverlayProp());
238    }
239
240    getGraphicsObjectHashmap<Box>()[id] = gobj;
241
242    sceneBoundsChanged();
243    _needsRedraw = true;
244    return true;
245}
246
247template <>
248bool Renderer::addGraphicsObject<Sphere>(const DataSetId& id)
249{
250    Sphere *gobj;
251    if ((gobj = getGraphicsObject<Sphere>(id)) != NULL) {
252        WARN("Replacing existing %s %s", gobj->getClassName(), id.c_str());
253        deleteGraphicsObject<Sphere>(id);
254    }
255
256    gobj = new Sphere();
257 
258    gobj->setDataSet(NULL, this);
259
260    if (gobj->getProp() == NULL &&
261        gobj->getOverlayProp() == NULL) {
262        delete gobj;
263        return false;
264    } else {
265        if (gobj->getProp())
266            _renderer->AddViewProp(gobj->getProp());
267        if (gobj->getOverlayProp())
268            _renderer->AddViewProp(gobj->getOverlayProp());
269    }
270
271    getGraphicsObjectHashmap<Sphere>()[id] = gobj;
272
273    sceneBoundsChanged();
274    _needsRedraw = true;
275    return true;
276}
277
278/**
279 * \brief Set the volume slice used for mapping volumetric data
280 */
281template <>
282void Renderer::setGraphicsObjectVolumeSlice<HeightMap>(const DataSetId& id, Axis axis, double ratio)
283{
284    HeightMapHashmap::iterator itr;
285
286    bool doAll = false;
287
288    if (id.compare("all") == 0) {
289        itr = _heightMaps.begin();
290        if (itr == _heightMaps.end())
291            return;
292        doAll = true;
293    } else {
294        itr = _heightMaps.find(id);
295    }
296
297    if (itr == _heightMaps.end()) {
298        ERROR("HeightMap not found: %s", id.c_str());
299        return;
300    }
301
302    do {
303        itr->second->selectVolumeSlice(axis, ratio);
304     } while (doAll && ++itr != _heightMaps.end());
305
306    sceneBoundsChanged();
307    _needsRedraw = true;
308}
309
310}
311
312using namespace VtkVis;
313
314GraphicsObject *
315Renderer::getGenericGraphicsObject(const DataSetId& id)
316{
317    GraphicsObject *gobj = NULL;
318
319    if ((gobj = getGraphicsObject<Arc>(id)) != NULL) {
320        return gobj;
321    }
322    if ((gobj = getGraphicsObject<Arrow>(id)) != NULL) {
323        return gobj;
324    }
325    if ((gobj = getGraphicsObject<Box>(id)) != NULL) {
326        return gobj;
327    }
328    if ((gobj = getGraphicsObject<Cone>(id)) != NULL) {
329        return gobj;
330    }
331    if ((gobj = getGraphicsObject<Cylinder>(id)) != NULL) {
332        return gobj;
333    }
334    if ((gobj = getGraphicsObject<Disk>(id)) != NULL) {
335        return gobj;
336    }
337    if ((gobj = getGraphicsObject<Line>(id)) != NULL) {
338        return gobj;
339    }
340    if ((gobj = getGraphicsObject<Polygon>(id)) != NULL) {
341        return gobj;
342    }
343    if ((gobj = getGraphicsObject<Sphere>(id)) != NULL) {
344        return gobj;
345    }
346    //
347    if ((gobj = getGraphicsObject<Contour2D>(id)) != NULL) {
348        return gobj;
349    }
350    if ((gobj = getGraphicsObject<Contour3D>(id)) != NULL) {
351        return gobj;
352    }
353    if ((gobj = getGraphicsObject<Cutplane>(id)) != NULL) {
354        return gobj;
355    }
356    if ((gobj = getGraphicsObject<Glyphs>(id)) != NULL) {
357        return gobj;
358    }
359    if ((gobj = getGraphicsObject<HeightMap>(id)) != NULL) {
360        return gobj;
361    }
362    if ((gobj = getGraphicsObject<LIC>(id)) != NULL) {
363        return gobj;
364    }
365    if ((gobj = getGraphicsObject<Molecule>(id)) != NULL) {
366        return gobj;
367    }
368    if ((gobj = getGraphicsObject<Outline>(id)) != NULL) {
369        return gobj;
370    }
371    if ((gobj = getGraphicsObject<PolyData>(id)) != NULL) {
372        return gobj;
373    }
374    if ((gobj = getGraphicsObject<PseudoColor>(id)) != NULL) {
375        return gobj;
376    }
377    if ((gobj = getGraphicsObject<Streamlines>(id)) != NULL) {
378        return gobj;
379    }
380    if ((gobj = getGraphicsObject<Volume>(id)) != NULL) {
381        return gobj;
382    }
383    if ((gobj = getGraphicsObject<Warp>(id)) != NULL) {
384        return gobj;
385    }
386    //
387    if ((gobj = getGraphicsObject<Group>(id)) != NULL) {
388        return gobj;
389    }
390
391    return NULL;
392}
393
394/**
395 * \brief Create a new Arc and associate it with an ID
396 */
397bool Renderer::addArc(const DataSetId& id,
398                      double center[3],
399                      double pt1[3],
400                      double normal[3],
401                      double angle)
402{
403    Arc *gobj;
404    if ((gobj = getGraphicsObject<Arc>(id)) != NULL) {
405        WARN("Replacing existing %s %s", gobj->getClassName(), id.c_str());
406        deleteGraphicsObject<Arc>(id);
407    }
408
409    gobj = new Arc();
410 
411    gobj->setDataSet(NULL, this);
412
413    if (gobj->getProp() == NULL &&
414        gobj->getOverlayProp() == NULL) {
415        delete gobj;
416        return false;
417    } else {
418        if (gobj->getProp())
419            _renderer->AddViewProp(gobj->getProp());
420        if (gobj->getOverlayProp())
421            _renderer->AddViewProp(gobj->getOverlayProp());
422    }
423
424    gobj->setCenter(center);
425    gobj->setStartPoint(pt1);
426    gobj->setNormal(normal);
427    gobj->setAngle(angle);
428
429    getGraphicsObjectHashmap<Arc>()[id] = gobj;
430
431    sceneBoundsChanged();
432    _needsRedraw = true;
433    return true;
434}
435
436/**
437 * \brief Set Arc resolution
438 */
439void Renderer::setArcResolution(const DataSetId& id, int res)
440{
441    ArcHashmap::iterator itr;
442
443    bool doAll = false;
444
445    if (id.compare("all") == 0) {
446        itr = _arcs.begin();
447        if (itr == _arcs.end())
448            return;
449        doAll = true;
450    } else {
451        itr = _arcs.find(id);
452    }
453    if (itr == _arcs.end()) {
454        ERROR("Arc not found: %s", id.c_str());
455        return;
456    }
457
458    do {
459        itr->second->setResolution(res);
460    } while (doAll && ++itr != _arcs.end());
461
462    sceneBoundsChanged();
463    _needsRedraw = true;
464}
465
466/**
467 * \brief Create a new Arrow and associate it with an ID
468 */
469bool Renderer::addArrow(const DataSetId& id, double tipRadius,
470                        double shaftRadius, double tipLength,
471                        bool flipNormals)
472{
473    Arrow *gobj;
474    if ((gobj = getGraphicsObject<Arrow>(id)) != NULL) {
475        WARN("Replacing existing %s %s", gobj->getClassName(), id.c_str());
476        deleteGraphicsObject<Arrow>(id);
477    }
478
479    gobj = new Arrow();
480 
481    gobj->setDataSet(NULL, this);
482
483    if (gobj->getProp() == NULL &&
484        gobj->getOverlayProp() == NULL) {
485        delete gobj;
486        return false;
487    } else {
488        if (gobj->getProp())
489            _renderer->AddViewProp(gobj->getProp());
490        if (gobj->getOverlayProp())
491            _renderer->AddViewProp(gobj->getOverlayProp());
492    }
493
494    gobj->setRadii(tipRadius, shaftRadius);
495    gobj->setTipLength(tipLength);
496    if (flipNormals)
497        gobj->flipNormals(flipNormals);
498
499    getGraphicsObjectHashmap<Arrow>()[id] = gobj;
500
501    sceneBoundsChanged();
502    _needsRedraw = true;
503    return true;
504}
505
506/**
507 * \brief Set Arrow resolution
508 */
509void Renderer::setArrowResolution(const DataSetId& id, int tipRes, int shaftRes)
510{
511    ArrowHashmap::iterator itr;
512
513    bool doAll = false;
514
515    if (id.compare("all") == 0) {
516        itr = _arrows.begin();
517        if (itr == _arrows.end())
518            return;
519        doAll = true;
520    } else {
521        itr = _arrows.find(id);
522    }
523    if (itr == _arrows.end()) {
524        ERROR("Arrow not found: %s", id.c_str());
525        return;
526    }
527
528    do {
529        itr->second->setResolution(tipRes, shaftRes);
530    } while (doAll && ++itr != _arrows.end());
531
532    sceneBoundsChanged();
533    _needsRedraw = true;
534}
535
536/**
537 * \brief Create a new Box and associate it with an ID
538 */
539bool Renderer::addBox(const DataSetId& id,
540                      double xLen, double yLen, double zLen,
541                      bool flipNormals)
542{
543    Box *gobj;
544    if ((gobj = getGraphicsObject<Box>(id)) != NULL) {
545        WARN("Replacing existing %s %s", gobj->getClassName(), id.c_str());
546        deleteGraphicsObject<Box>(id);
547    }
548
549    gobj = new Box();
550 
551    gobj->setDataSet(NULL, this);
552
553    if (gobj->getProp() == NULL &&
554        gobj->getOverlayProp() == NULL) {
555        delete gobj;
556        return false;
557    } else {
558        if (gobj->getProp())
559            _renderer->AddViewProp(gobj->getProp());
560        if (gobj->getOverlayProp())
561            _renderer->AddViewProp(gobj->getOverlayProp());
562    }
563
564    gobj->setSize(xLen, yLen, zLen);
565    if (flipNormals)
566        gobj->flipNormals(flipNormals);
567
568    getGraphicsObjectHashmap<Box>()[id] = gobj;
569
570    sceneBoundsChanged();
571    _needsRedraw = true;
572    return true;
573}
574
575/**
576 * \brief Create a new Cone and associate it with an ID
577 */
578bool Renderer::addCone(const DataSetId& id, double radius, double height,
579                       bool cap, bool flipNormals)
580{
581    Cone *gobj;
582    if ((gobj = getGraphicsObject<Cone>(id)) != NULL) {
583        WARN("Replacing existing %s %s", gobj->getClassName(), id.c_str());
584        deleteGraphicsObject<Cone>(id);
585    }
586
587    gobj = new Cone();
588 
589    gobj->setDataSet(NULL, this);
590
591    if (gobj->getProp() == NULL &&
592        gobj->getOverlayProp() == NULL) {
593        delete gobj;
594        return false;
595    } else {
596        if (gobj->getProp())
597            _renderer->AddViewProp(gobj->getProp());
598        if (gobj->getOverlayProp())
599            _renderer->AddViewProp(gobj->getOverlayProp());
600    }
601
602    gobj->setRadius(radius);
603    gobj->setHeight(height);
604    gobj->setCapping(cap);
605    if (flipNormals)
606        gobj->flipNormals(flipNormals);
607
608    getGraphicsObjectHashmap<Cone>()[id] = gobj;
609
610    sceneBoundsChanged();
611    _needsRedraw = true;
612    return true;
613}
614
615/**
616 * \brief Set Cone resolution
617 */
618void Renderer::setConeResolution(const DataSetId& id, int res)
619{
620    ConeHashmap::iterator itr;
621
622    bool doAll = false;
623
624    if (id.compare("all") == 0) {
625        itr = _cones.begin();
626        if (itr == _cones.end())
627            return;
628        doAll = true;
629    } else {
630        itr = _cones.find(id);
631    }
632    if (itr == _cones.end()) {
633        ERROR("Cone not found: %s", id.c_str());
634        return;
635    }
636
637    do {
638        itr->second->setResolution(res);
639    } while (doAll && ++itr != _cones.end());
640
641    sceneBoundsChanged();
642    _needsRedraw = true;
643}
644
645/**
646 * \brief Create a new Contour2D and associate it with the named DataSet
647 */
648bool Renderer::addContour2D(const DataSetId& id, int numContours)
649{
650    DataSetHashmap::iterator itr;
651
652    bool doAll = false;
653
654    if (id.compare("all") == 0) {
655        itr = _dataSets.begin();
656    } else {
657        itr = _dataSets.find(id);
658    }
659    if (itr == _dataSets.end()) {
660        ERROR("Unknown dataset %s", id.c_str());
661        return false;
662    }
663
664    do {
665        DataSet *ds = itr->second;
666        const DataSetId& dsID = ds->getName();
667
668        if (getGraphicsObject<Contour2D>(dsID)) {
669            WARN("Replacing existing Contour2D %s", dsID.c_str());
670            deleteGraphicsObject<Contour2D>(dsID);
671        }
672
673        Contour2D *contour = new Contour2D(numContours);
674 
675        contour->setDataSet(ds, this);
676
677        if (contour->getProp() == NULL) {
678            delete contour;
679            return false;
680        } else {
681            _renderer->AddViewProp(contour->getProp());
682        }
683
684        _contour2Ds[dsID] = contour;
685    } while (doAll && ++itr != _dataSets.end());
686
687    sceneBoundsChanged();
688    _needsRedraw = true;
689    return true;
690}
691
692/**
693 * \brief Create a new Contour2D and associate it with the named DataSet
694 */
695bool Renderer::addContour2D(const DataSetId& id, const std::vector<double>& contours)
696{
697    DataSetHashmap::iterator itr;
698
699    bool doAll = false;
700
701    if (id.compare("all") == 0) {
702        itr = _dataSets.begin();
703    } else {
704        itr = _dataSets.find(id);
705    }
706    if (itr == _dataSets.end()) {
707        ERROR("Unknown dataset %s", id.c_str());
708        return false;
709    }
710
711    do {
712        DataSet *ds = itr->second;
713        const DataSetId& dsID = ds->getName();
714
715        if (getGraphicsObject<Contour2D>(dsID)) {
716            WARN("Replacing existing Contour2D %s", dsID.c_str());
717            deleteGraphicsObject<Contour2D>(dsID);
718        }
719
720        Contour2D *contour = new Contour2D(contours);
721
722        contour->setDataSet(ds, this);
723
724        if (contour->getProp() == NULL) {
725            delete contour;
726            return false;
727        } else {
728            _renderer->AddViewProp(contour->getProp());
729        }
730
731        _contour2Ds[dsID] = contour;
732    } while (doAll && ++itr != _dataSets.end());
733
734    sceneBoundsChanged();
735    _needsRedraw = true;
736    return true;
737}
738
739/**
740 * \brief Set the number of equally spaced contour isolines for the given DataSet
741 */
742void Renderer::setContour2DNumContours(const DataSetId& id, int numContours)
743{
744    Contour2DHashmap::iterator itr;
745
746    bool doAll = false;
747
748    if (id.compare("all") == 0) {
749        itr = _contour2Ds.begin();
750        doAll = true;
751    } else {
752        itr = _contour2Ds.find(id);
753    }
754    if (itr == _contour2Ds.end()) {
755        ERROR("Contour2D not found: %s", id.c_str());
756        return;
757    }
758
759    do {
760        itr->second->setNumContours(numContours);
761    } while (doAll && ++itr != _contour2Ds.end());
762
763    sceneBoundsChanged();
764    _needsRedraw = true;
765}
766
767/**
768 * \brief Set the number of equally spaced isosurfaces for the given DataSet
769 */
770void Renderer::setContour2DContourField(const DataSetId& id, const char *fieldName)
771{
772    Contour2DHashmap::iterator itr;
773
774    bool doAll = false;
775
776    if (id.compare("all") == 0) {
777        itr = _contour2Ds.begin();
778        doAll = true;
779    } else {
780        itr = _contour2Ds.find(id);
781    }
782    if (itr == _contour2Ds.end()) {
783        ERROR("Contour2D not found: %s", id.c_str());
784        return;
785    }
786
787    do {
788        itr->second->setContourField(fieldName);
789     } while (doAll && ++itr != _contour2Ds.end());
790
791    sceneBoundsChanged();
792    _needsRedraw = true;
793}
794
795/**
796 * \brief Set a list of isovalues for the given DataSet
797 */
798void Renderer::setContour2DContourList(const DataSetId& id, const std::vector<double>& contours)
799{
800    Contour2DHashmap::iterator itr;
801
802    bool doAll = false;
803
804    if (id.compare("all") == 0) {
805        itr = _contour2Ds.begin();
806        doAll = true;
807    } else {
808        itr = _contour2Ds.find(id);
809    }
810    if (itr == _contour2Ds.end()) {
811        ERROR("Contour2D not found: %s", id.c_str());
812        return;
813    }
814
815    do {
816        itr->second->setContourList(contours);
817    } while (doAll && ++itr != _contour2Ds.end());
818
819    sceneBoundsChanged();
820     _needsRedraw = true;
821}
822
823/**
824 * \brief Set the color mode for the specified DataSet
825 */
826void Renderer::setContour2DColorMode(const DataSetId& id,
827                                     Contour2D::ColorMode mode,
828                                     DataSet::DataAttributeType type,
829                                     const char *name, double range[2])
830{
831    Contour2DHashmap::iterator itr;
832
833    bool doAll = false;
834
835    if (id.compare("all") == 0) {
836        itr = _contour2Ds.begin();
837        if (itr == _contour2Ds.end())
838            return;
839        doAll = true;
840    } else {
841        itr = _contour2Ds.find(id);
842    }
843    if (itr == _contour2Ds.end()) {
844        ERROR("Contour2D not found: %s", id.c_str());
845        return;
846    }
847
848    do {
849        itr->second->setColorMode(mode, type, name, range);
850    } while (doAll && ++itr != _contour2Ds.end());
851
852    _needsRedraw = true;
853}
854
855/**
856 * \brief Set the color mode for the specified DataSet
857 */
858void Renderer::setContour2DColorMode(const DataSetId& id,
859                                     Contour2D::ColorMode mode,
860                                     const char *name, double range[2])
861{
862    Contour2DHashmap::iterator itr;
863
864    bool doAll = false;
865
866    if (id.compare("all") == 0) {
867        itr = _contour2Ds.begin();
868        if (itr == _contour2Ds.end())
869            return;
870        doAll = true;
871    } else {
872        itr = _contour2Ds.find(id);
873    }
874    if (itr == _contour2Ds.end()) {
875        ERROR("Contour2D not found: %s", id.c_str());
876        return;
877    }
878
879    do {
880        itr->second->setColorMode(mode, name, range);
881    } while (doAll && ++itr != _contour2Ds.end());
882
883    _needsRedraw = true;
884}
885
886/**
887 * \brief Create a new Contour3D and associate it with the named DataSet
888 */
889bool Renderer::addContour3D(const DataSetId& id, int numContours)
890{
891    DataSetHashmap::iterator itr;
892
893    bool doAll = false;
894
895    if (id.compare("all") == 0) {
896        itr = _dataSets.begin();
897    } else {
898        itr = _dataSets.find(id);
899    }
900    if (itr == _dataSets.end()) {
901        ERROR("Unknown dataset %s", id.c_str());
902        return false;
903    }
904
905    do {
906        DataSet *ds = itr->second;
907        const DataSetId& dsID = ds->getName();
908
909        if (getGraphicsObject<Contour3D>(dsID)) {
910            WARN("Replacing existing Contour3D %s", dsID.c_str());
911            deleteGraphicsObject<Contour3D>(dsID);
912        }
913
914        Contour3D *contour = new Contour3D(numContours);
915
916        contour->setDataSet(ds, this);
917
918        if (contour->getProp() == NULL) {
919            delete contour;
920            return false;
921        } else {
922            _renderer->AddViewProp(contour->getProp());
923        }
924
925        _contour3Ds[dsID] = contour;
926    } while (doAll && ++itr != _dataSets.end());
927
928    sceneBoundsChanged();
929    _needsRedraw = true;
930    return true;
931}
932
933/**
934 * \brief Create a new Contour3D and associate it with the named DataSet
935 */
936bool Renderer::addContour3D(const DataSetId& id,const std::vector<double>& contours)
937{
938    DataSetHashmap::iterator itr;
939
940    bool doAll = false;
941
942    if (id.compare("all") == 0) {
943        itr = _dataSets.begin();
944    } else {
945        itr = _dataSets.find(id);
946    }
947    if (itr == _dataSets.end()) {
948        ERROR("Unknown dataset %s", id.c_str());
949        return false;
950    }
951
952    do {
953        DataSet *ds = itr->second;
954        const DataSetId& dsID = ds->getName();
955
956        if (getGraphicsObject<Contour3D>(dsID)) {
957            WARN("Replacing existing Contour3D %s", dsID.c_str());
958            deleteGraphicsObject<Contour3D>(dsID);
959        }
960
961        Contour3D *contour = new Contour3D(contours);
962
963        contour->setDataSet(ds, this);
964
965        if (contour->getProp() == NULL) {
966            delete contour;
967            return false;
968        } else {
969            _renderer->AddViewProp(contour->getProp());
970        }
971
972        _contour3Ds[dsID] = contour;
973    } while (doAll && ++itr != _dataSets.end());
974
975    sceneBoundsChanged();
976    _needsRedraw = true;
977    return true;
978}
979
980/**
981 * \brief Set the number of equally spaced isosurfaces for the given DataSet
982 */
983void Renderer::setContour3DContourField(const DataSetId& id, const char *fieldName)
984{
985    Contour3DHashmap::iterator itr;
986
987    bool doAll = false;
988
989    if (id.compare("all") == 0) {
990        itr = _contour3Ds.begin();
991        doAll = true;
992    } else {
993        itr = _contour3Ds.find(id);
994    }
995    if (itr == _contour3Ds.end()) {
996        ERROR("Contour3D not found: %s", id.c_str());
997        return;
998    }
999
1000    do {
1001        itr->second->setContourField(fieldName);
1002     } while (doAll && ++itr != _contour3Ds.end());
1003
1004    sceneBoundsChanged();
1005    _needsRedraw = true;
1006}
1007
1008/**
1009 * \brief Set the number of equally spaced isosurfaces for the given DataSet
1010 */
1011void Renderer::setContour3DNumContours(const DataSetId& id, int numContours)
1012{
1013    Contour3DHashmap::iterator itr;
1014
1015    bool doAll = false;
1016
1017    if (id.compare("all") == 0) {
1018        itr = _contour3Ds.begin();
1019        doAll = true;
1020    } else {
1021        itr = _contour3Ds.find(id);
1022    }
1023    if (itr == _contour3Ds.end()) {
1024        ERROR("Contour3D not found: %s", id.c_str());
1025        return;
1026    }
1027
1028    do {
1029        itr->second->setNumContours(numContours);
1030     } while (doAll && ++itr != _contour3Ds.end());
1031
1032    sceneBoundsChanged();
1033    _needsRedraw = true;
1034}
1035
1036/**
1037 * \brief Set a list of isovalues for the given DataSet
1038 */
1039void Renderer::setContour3DContourList(const DataSetId& id, const std::vector<double>& contours)
1040{
1041    Contour3DHashmap::iterator itr;
1042
1043    bool doAll = false;
1044
1045    if (id.compare("all") == 0) {
1046        itr = _contour3Ds.begin();
1047        doAll = true;
1048    } else {
1049        itr = _contour3Ds.find(id);
1050    }
1051    if (itr == _contour3Ds.end()) {
1052        ERROR("Contour3D not found: %s", id.c_str());
1053        return;
1054    }
1055
1056    do {
1057        itr->second->setContourList(contours);
1058    } while (doAll && ++itr != _contour3Ds.end());
1059
1060    sceneBoundsChanged();
1061    _needsRedraw = true;
1062}
1063
1064/**
1065 * \brief Set the color mode for the specified DataSet
1066 */
1067void Renderer::setContour3DColorMode(const DataSetId& id,
1068                                     Contour3D::ColorMode mode,
1069                                     DataSet::DataAttributeType type,
1070                                     const char *name, double range[2])
1071{
1072    Contour3DHashmap::iterator itr;
1073
1074    bool doAll = false;
1075
1076    if (id.compare("all") == 0) {
1077        itr = _contour3Ds.begin();
1078        if (itr == _contour3Ds.end())
1079            return;
1080        doAll = true;
1081    } else {
1082        itr = _contour3Ds.find(id);
1083    }
1084    if (itr == _contour3Ds.end()) {
1085        ERROR("Contour3D not found: %s", id.c_str());
1086        return;
1087    }
1088
1089    do {
1090        itr->second->setColorMode(mode, type, name, range);
1091    } while (doAll && ++itr != _contour3Ds.end());
1092
1093    _needsRedraw = true;
1094}
1095
1096/**
1097 * \brief Set the color mode for the specified DataSet
1098 */
1099void Renderer::setContour3DColorMode(const DataSetId& id,
1100                                     Contour3D::ColorMode mode,
1101                                     const char *name, double range[2])
1102{
1103    Contour3DHashmap::iterator itr;
1104
1105    bool doAll = false;
1106
1107    if (id.compare("all") == 0) {
1108        itr = _contour3Ds.begin();
1109        if (itr == _contour3Ds.end())
1110            return;
1111        doAll = true;
1112    } else {
1113        itr = _contour3Ds.find(id);
1114    }
1115    if (itr == _contour3Ds.end()) {
1116        ERROR("Contour3D not found: %s", id.c_str());
1117        return;
1118    }
1119
1120    do {
1121        itr->second->setColorMode(mode, name, range);
1122    } while (doAll && ++itr != _contour3Ds.end());
1123
1124    _needsRedraw = true;
1125}
1126
1127/**
1128 * \brief Set the visibility of cutplane outlines
1129 */
1130void Renderer::setCutplaneOutlineVisibility(const DataSetId& id, bool state)
1131{
1132    CutplaneHashmap::iterator itr;
1133
1134    bool doAll = false;
1135
1136    if (id.compare("all") == 0) {
1137        itr = _cutplanes.begin();
1138        if (itr == _cutplanes.end())
1139            return;
1140        doAll = true;
1141    } else {
1142        itr = _cutplanes.find(id);
1143    }
1144
1145    if (itr == _cutplanes.end()) {
1146        ERROR("Cutplane not found: %s", id.c_str());
1147        return;
1148    }
1149
1150    do {
1151        itr->second->setOutlineVisibility(state);
1152     } while (doAll && ++itr != _cutplanes.end());
1153
1154    sceneBoundsChanged();
1155    _needsRedraw = true;
1156}
1157
1158/**
1159 * \brief Set the visibility of slices in one of the three axes
1160 */
1161void Renderer::setCutplaneSliceVisibility(const DataSetId& id, Axis axis, bool state)
1162{
1163    CutplaneHashmap::iterator itr;
1164
1165    bool doAll = false;
1166
1167    if (id.compare("all") == 0) {
1168        itr = _cutplanes.begin();
1169        if (itr == _cutplanes.end())
1170            return;
1171        doAll = true;
1172    } else {
1173        itr = _cutplanes.find(id);
1174    }
1175
1176    if (itr == _cutplanes.end()) {
1177        ERROR("Cutplane not found: %s", id.c_str());
1178        return;
1179    }
1180
1181    do {
1182        itr->second->setSliceVisibility(axis, state);
1183     } while (doAll && ++itr != _cutplanes.end());
1184
1185    sceneBoundsChanged();
1186    _needsRedraw = true;
1187}
1188
1189/**
1190 * \brief Set the point cloud render style for the specified DataSet
1191 */
1192void Renderer::setCutplaneCloudStyle(const DataSetId& id,
1193                                     Cutplane::CloudStyle style)
1194{
1195    CutplaneHashmap::iterator itr;
1196
1197    bool doAll = false;
1198
1199    if (id.compare("all") == 0) {
1200        itr = _cutplanes.begin();
1201        if (itr == _cutplanes.end())
1202            return;
1203        doAll = true;
1204    } else {
1205        itr = _cutplanes.find(id);
1206    }
1207    if (itr == _cutplanes.end()) {
1208        ERROR("Cutplane not found: %s", id.c_str());
1209        return;
1210    }
1211
1212    do {
1213        itr->second->setCloudStyle(style);
1214    } while (doAll && ++itr != _cutplanes.end());
1215
1216    _needsRedraw = true;
1217}
1218
1219/**
1220 * \brief Set the color mode for the specified DataSet
1221 */
1222void Renderer::setCutplaneColorMode(const DataSetId& id,
1223                                    Cutplane::ColorMode mode,
1224                                    DataSet::DataAttributeType type,
1225                                    const char *name, double range[2])
1226{
1227    CutplaneHashmap::iterator itr;
1228
1229    bool doAll = false;
1230
1231    if (id.compare("all") == 0) {
1232        itr = _cutplanes.begin();
1233        if (itr == _cutplanes.end())
1234            return;
1235        doAll = true;
1236    } else {
1237        itr = _cutplanes.find(id);
1238    }
1239    if (itr == _cutplanes.end()) {
1240        ERROR("Cutplane not found: %s", id.c_str());
1241        return;
1242    }
1243
1244    do {
1245        itr->second->setColorMode(mode, type, name, range);
1246    } while (doAll && ++itr != _cutplanes.end());
1247
1248    _needsRedraw = true;
1249}
1250
1251/**
1252 * \brief Set the color mode for the specified DataSet
1253 */
1254void Renderer::setCutplaneColorMode(const DataSetId& id,
1255                                    Cutplane::ColorMode mode,
1256                                    const char *name, double range[2])
1257{
1258    CutplaneHashmap::iterator itr;
1259
1260    bool doAll = false;
1261
1262    if (id.compare("all") == 0) {
1263        itr = _cutplanes.begin();
1264        if (itr == _cutplanes.end())
1265            return;
1266        doAll = true;
1267    } else {
1268        itr = _cutplanes.find(id);
1269    }
1270    if (itr == _cutplanes.end()) {
1271        ERROR("Cutplane not found: %s", id.c_str());
1272        return;
1273    }
1274
1275    do {
1276        itr->second->setColorMode(mode, name, range);
1277    } while (doAll && ++itr != _cutplanes.end());
1278
1279    _needsRedraw = true;
1280}
1281
1282/**
1283 * \brief Create a new Cylinder and associate it with an ID
1284 */
1285bool Renderer::addCylinder(const DataSetId& id, double radius, double height,
1286                           bool cap, bool flipNormals)
1287{
1288    Cylinder *gobj;
1289    if ((gobj = getGraphicsObject<Cylinder>(id)) != NULL) {
1290        WARN("Replacing existing %s %s", gobj->getClassName(), id.c_str());
1291        deleteGraphicsObject<Cylinder>(id);
1292    }
1293
1294    gobj = new Cylinder();
1295 
1296    gobj->setDataSet(NULL, this);
1297
1298    if (gobj->getProp() == NULL &&
1299        gobj->getOverlayProp() == NULL) {
1300        delete gobj;
1301        return false;
1302    } else {
1303        if (gobj->getProp())
1304            _renderer->AddViewProp(gobj->getProp());
1305        if (gobj->getOverlayProp())
1306            _renderer->AddViewProp(gobj->getOverlayProp());
1307    }
1308
1309    gobj->setRadius(radius);
1310    gobj->setHeight(height);
1311    gobj->setCapping(cap);
1312    if (flipNormals)
1313        gobj->flipNormals(flipNormals);
1314
1315    getGraphicsObjectHashmap<Cylinder>()[id] = gobj;
1316
1317    sceneBoundsChanged();
1318    _needsRedraw = true;
1319    return true;
1320}
1321
1322/**
1323 * \brief Set Cylinder capping
1324 */
1325void Renderer::setCylinderCapping(const DataSetId& id, bool state)
1326{
1327    CylinderHashmap::iterator itr;
1328
1329    bool doAll = false;
1330
1331    if (id.compare("all") == 0) {
1332        itr = _cylinders.begin();
1333        if (itr == _cylinders.end())
1334            return;
1335        doAll = true;
1336    } else {
1337        itr = _cylinders.find(id);
1338    }
1339    if (itr == _cylinders.end()) {
1340        ERROR("Cylinder not found: %s", id.c_str());
1341        return;
1342    }
1343
1344    do {
1345        itr->second->setCapping(state);
1346    } while (doAll && ++itr != _cylinders.end());
1347
1348    sceneBoundsChanged();
1349    _needsRedraw = true;
1350}
1351
1352/**
1353 * \brief Set Cylinder resolution
1354 */
1355void Renderer::setCylinderResolution(const DataSetId& id, int res)
1356{
1357    CylinderHashmap::iterator itr;
1358
1359    bool doAll = false;
1360
1361    if (id.compare("all") == 0) {
1362        itr = _cylinders.begin();
1363        if (itr == _cylinders.end())
1364            return;
1365        doAll = true;
1366    } else {
1367        itr = _cylinders.find(id);
1368    }
1369    if (itr == _cylinders.end()) {
1370        ERROR("Cylinder not found: %s", id.c_str());
1371        return;
1372    }
1373
1374    do {
1375        itr->second->setResolution(res);
1376    } while (doAll && ++itr != _cylinders.end());
1377
1378    sceneBoundsChanged();
1379    _needsRedraw = true;
1380}
1381
1382/**
1383 * \brief Create a new Disk and associate it with an ID
1384 */
1385bool Renderer::addDisk(const DataSetId& id,
1386                       double innerRadius,
1387                       double outerRadius,
1388                       bool flipNormals)
1389{
1390    Disk *gobj;
1391    if ((gobj = getGraphicsObject<Disk>(id)) != NULL) {
1392        WARN("Replacing existing %s %s", gobj->getClassName(), id.c_str());
1393        deleteGraphicsObject<Disk>(id);
1394    }
1395
1396    gobj = new Disk();
1397 
1398    gobj->setDataSet(NULL, this);
1399
1400    if (gobj->getProp() == NULL &&
1401        gobj->getOverlayProp() == NULL) {
1402        delete gobj;
1403        return false;
1404    } else {
1405        if (gobj->getProp())
1406            _renderer->AddViewProp(gobj->getProp());
1407        if (gobj->getOverlayProp())
1408            _renderer->AddViewProp(gobj->getOverlayProp());
1409    }
1410
1411    gobj->setRadii(innerRadius, outerRadius);
1412    if (flipNormals)
1413        gobj->flipNormals(flipNormals);
1414
1415    getGraphicsObjectHashmap<Disk>()[id] = gobj;
1416
1417    sceneBoundsChanged();
1418    _needsRedraw = true;
1419    return true;
1420}
1421
1422/**
1423 * \brief Set Disk resolution
1424 */
1425void Renderer::setDiskResolution(const DataSetId& id, int resRadial, int resCircum)
1426{
1427    DiskHashmap::iterator itr;
1428
1429    bool doAll = false;
1430
1431    if (id.compare("all") == 0) {
1432        itr = _disks.begin();
1433        if (itr == _disks.end())
1434            return;
1435        doAll = true;
1436    } else {
1437        itr = _disks.find(id);
1438    }
1439    if (itr == _disks.end()) {
1440        ERROR("Disk not found: %s", id.c_str());
1441        return;
1442    }
1443
1444    do {
1445        itr->second->setResolution(resRadial, resCircum);
1446    } while (doAll && ++itr != _disks.end());
1447
1448    sceneBoundsChanged();
1449    _needsRedraw = true;
1450}
1451
1452/**
1453 * \brief Create a new Glyphs and associate it with the named DataSet
1454 */
1455bool Renderer::addGlyphs(const DataSetId& id, Glyphs::GlyphShape shape)
1456{
1457    DataSetHashmap::iterator itr;
1458
1459    bool doAll = false;
1460
1461    if (id.compare("all") == 0) {
1462        itr = _dataSets.begin();
1463    } else {
1464        itr = _dataSets.find(id);
1465    }
1466    if (itr == _dataSets.end()) {
1467        ERROR("Unknown dataset %s", id.c_str());
1468        return false;
1469    }
1470
1471    do {
1472        DataSet *ds = itr->second;
1473        const DataSetId& dsID = ds->getName();
1474
1475        if (getGraphicsObject<Glyphs>(dsID)) {
1476            WARN("Replacing existing Glyphs %s", dsID.c_str());
1477            deleteGraphicsObject<Glyphs>(dsID);
1478        }
1479
1480        Glyphs *glyphs = new Glyphs(shape);
1481
1482        glyphs->setDataSet(ds, this);
1483
1484        if (glyphs->getProp() == NULL) {
1485            delete glyphs;
1486            return false;
1487        } else {
1488            _renderer->AddViewProp(glyphs->getProp());
1489        }
1490
1491        _glyphs[dsID] = glyphs;
1492    } while (doAll && ++itr != _dataSets.end());
1493
1494    sceneBoundsChanged();
1495    _needsRedraw = true;
1496    return true;
1497}
1498
1499/**
1500 * \brief Set the color mode for the specified DataSet
1501 */
1502void Renderer::setGlyphsColorMode(const DataSetId& id,
1503                                  Glyphs::ColorMode mode,
1504                                  const char *name, double range[2])
1505{
1506    GlyphsHashmap::iterator itr;
1507
1508    bool doAll = false;
1509
1510    if (id.compare("all") == 0) {
1511        itr = _glyphs.begin();
1512        if (itr == _glyphs.end())
1513            return;
1514        doAll = true;
1515    } else {
1516        itr = _glyphs.find(id);
1517    }
1518    if (itr == _glyphs.end()) {
1519        ERROR("Glyphs not found: %s", id.c_str());
1520        return;
1521    }
1522
1523    do {
1524        itr->second->setColorMode(mode, name, range);
1525    } while (doAll && ++itr != _glyphs.end());
1526
1527    _needsRedraw = true;
1528}
1529
1530/**
1531 * \brief Controls the array used to scale glyphs for the given DataSet
1532 */
1533void Renderer::setGlyphsScalingMode(const DataSetId& id,
1534                                    Glyphs::ScalingMode mode,
1535                                    const char *name, double range[2])
1536{
1537    GlyphsHashmap::iterator itr;
1538
1539    bool doAll = false;
1540
1541    if (id.compare("all") == 0) {
1542        itr = _glyphs.begin();
1543        if (itr == _glyphs.end())
1544            return;
1545        doAll = true;
1546    } else {
1547        itr = _glyphs.find(id);
1548    }
1549    if (itr == _glyphs.end()) {
1550        ERROR("Glyphs not found: %s", id.c_str());
1551        return;
1552    }
1553
1554    do {
1555        itr->second->setScalingMode(mode, name, range);
1556    } while (doAll && ++itr != _glyphs.end());
1557
1558    sceneBoundsChanged();
1559    _needsRedraw = true;
1560}
1561
1562/**
1563 * \brief Controls if field data range is normalized to [0,1] before
1564 * applying scale factor for the given DataSet
1565 */
1566void Renderer::setGlyphsNormalizeScale(const DataSetId& id, bool normalize)
1567{
1568    GlyphsHashmap::iterator itr;
1569
1570    bool doAll = false;
1571
1572    if (id.compare("all") == 0) {
1573        itr = _glyphs.begin();
1574        if (itr == _glyphs.end())
1575            return;
1576        doAll = true;
1577    } else {
1578        itr = _glyphs.find(id);
1579    }
1580    if (itr == _glyphs.end()) {
1581        ERROR("Glyphs not found: %s", id.c_str());
1582        return;
1583    }
1584
1585    do {
1586        itr->second->setNormalizeScale(normalize);
1587    } while (doAll && ++itr != _glyphs.end());
1588
1589    sceneBoundsChanged();
1590    _needsRedraw = true;
1591}
1592
1593/**
1594 * \brief Controls if glyphs are oriented from a vector field for the
1595 * given DataSet
1596 */
1597void Renderer::setGlyphsOrientMode(const DataSetId& id, bool state,
1598                                   const char *name)
1599{
1600    GlyphsHashmap::iterator itr;
1601
1602    bool doAll = false;
1603
1604    if (id.compare("all") == 0) {
1605        itr = _glyphs.begin();
1606        if (itr == _glyphs.end())
1607            return;
1608        doAll = true;
1609    } else {
1610        itr = _glyphs.find(id);
1611    }
1612    if (itr == _glyphs.end()) {
1613        ERROR("Glyphs not found: %s", id.c_str());
1614        return;
1615    }
1616
1617    do {
1618        itr->second->setOrientMode(state, name);
1619    } while (doAll && ++itr != _glyphs.end());
1620
1621    sceneBoundsChanged();
1622    _needsRedraw = true;
1623}
1624
1625/**
1626 * \brief Set glyph shape resolution
1627 */
1628void Renderer::setGlyphsQuality(const DataSetId& id, double quality)
1629{
1630    GlyphsHashmap::iterator itr;
1631
1632    bool doAll = false;
1633
1634    if (id.compare("all") == 0) {
1635        itr = _glyphs.begin();
1636        if (itr == _glyphs.end())
1637            return;
1638        doAll = true;
1639    } else {
1640        itr = _glyphs.find(id);
1641    }
1642    if (itr == _glyphs.end()) {
1643        ERROR("Glyphs not found: %s", id.c_str());
1644        return;
1645    }
1646
1647    do {
1648        itr->second->setQuality(quality);
1649    } while (doAll && ++itr != _glyphs.end());
1650
1651    sceneBoundsChanged();
1652    _needsRedraw = true;
1653}
1654
1655/**
1656 * \brief Set the shape of Glyphs for the given DataSet
1657 */
1658void Renderer::setGlyphsShape(const DataSetId& id, Glyphs::GlyphShape shape)
1659{
1660    GlyphsHashmap::iterator itr;
1661
1662    bool doAll = false;
1663
1664    if (id.compare("all") == 0) {
1665        itr = _glyphs.begin();
1666        if (itr == _glyphs.end())
1667            return;
1668        doAll = true;
1669    } else {
1670        itr = _glyphs.find(id);
1671    }
1672    if (itr == _glyphs.end()) {
1673        ERROR("Glyphs not found: %s", id.c_str());
1674        return;
1675    }
1676
1677    do {
1678        itr->second->setGlyphShape(shape);
1679    } while (doAll && ++itr != _glyphs.end());
1680
1681    sceneBoundsChanged();
1682    _needsRedraw = true;
1683}
1684
1685/**
1686 * \brief Set the glyph scaling factor for the given DataSet
1687 */
1688void Renderer::setGlyphsScaleFactor(const DataSetId& id, double scale)
1689{
1690    GlyphsHashmap::iterator itr;
1691
1692    bool doAll = false;
1693
1694    if (id.compare("all") == 0) {
1695        itr = _glyphs.begin();
1696        if (itr == _glyphs.end())
1697            return;
1698        doAll = true;
1699    } else {
1700        itr = _glyphs.find(id);
1701    }
1702    if (itr == _glyphs.end()) {
1703        ERROR("Glyphs not found: %s", id.c_str());
1704        return;
1705    }
1706
1707    do {
1708        itr->second->setScaleFactor(scale);
1709    } while (doAll && ++itr != _glyphs.end());
1710
1711    sceneBoundsChanged();
1712    _needsRedraw = true;
1713}
1714
1715bool Renderer::addGroup(const DataSetId& id, const std::vector<Group::NodeId>& nodeList)
1716{
1717    if (id.compare("all") == 0) {
1718        addChildrenToGroup(id, nodeList);
1719        return true;
1720    }
1721
1722    Group *gobj;
1723    if ((gobj = getGraphicsObject<Group>(id)) != NULL) {
1724        // Group exists, so add nodes to it
1725        addChildrenToGroup(id, nodeList);
1726        return true;
1727    }
1728
1729    gobj = new Group();
1730 
1731    gobj->setDataSet(NULL, this);
1732
1733    if (gobj->getProp() == NULL &&
1734        gobj->getOverlayProp() == NULL) {
1735        delete gobj;
1736        return false;
1737    } else {
1738        if (gobj->getProp())
1739            _renderer->AddViewProp(gobj->getProp());
1740        if (gobj->getOverlayProp())
1741            _renderer->AddViewProp(gobj->getOverlayProp());
1742    }
1743
1744    for (std::vector<Group::NodeId>::const_iterator itr = nodeList.begin();
1745         itr != nodeList.end(); ++itr) {
1746        GraphicsObject *node = getGenericGraphicsObject(*itr);
1747        if (node != NULL) {
1748            if (node->getProp())
1749                _renderer->RemoveViewProp(node->getProp());
1750            if (node->getOverlayProp())
1751                _renderer->RemoveViewProp(node->getOverlayProp());
1752            gobj->addChild(*itr, node);
1753        } else {
1754            ERROR("Can't find node: %s", itr->c_str());
1755        }
1756    }
1757
1758    getGraphicsObjectHashmap<Group>()[id] = gobj;
1759
1760    sceneBoundsChanged();
1761    _needsRedraw = true;
1762    return true;
1763}
1764
1765void Renderer::addChildrenToGroup(const DataSetId& id, const std::vector<Group::NodeId>& nodeList)
1766{
1767    GroupHashmap::iterator itr;
1768
1769    bool doAll = false;
1770
1771    if (id.compare("all") == 0) {
1772        itr = _groups.begin();
1773        if (itr == _groups.end())
1774            return;
1775        doAll = true;
1776    } else {
1777        itr = _groups.find(id);
1778    }
1779
1780    if (itr == _groups.end()) {
1781        ERROR("Group not found: %s", id.c_str());
1782        return;
1783    }
1784
1785    do {
1786        for (std::vector<Group::NodeId>::const_iterator citr = nodeList.begin();
1787             citr != nodeList.end(); ++citr) {
1788            GraphicsObject *node = getGenericGraphicsObject(*citr);
1789            if (node != NULL) {
1790                if (node->getProp())
1791                    _renderer->RemoveViewProp(node->getProp());
1792                if (node->getOverlayProp())
1793                    _renderer->RemoveViewProp(node->getOverlayProp());
1794                itr->second->addChild(*citr, node);
1795            } else {
1796                ERROR("Can't find node: %s", citr->c_str());
1797            }
1798        }
1799     } while (doAll && ++itr != _groups.end());
1800
1801    sceneBoundsChanged();
1802    _needsRedraw = true;
1803}
1804
1805void Renderer::removeChildrenFromGroup(const DataSetId& id, const std::vector<Group::NodeId>& nodeList)
1806{
1807    GroupHashmap::iterator itr;
1808
1809    bool doAll = false;
1810
1811    if (id.compare("all") == 0) {
1812        itr = _groups.begin();
1813        if (itr == _groups.end())
1814            return;
1815        doAll = true;
1816    } else {
1817        itr = _groups.find(id);
1818    }
1819
1820    if (itr == _groups.end()) {
1821        ERROR("Group not found: %s", id.c_str());
1822        return;
1823    }
1824
1825    do {
1826        for (std::vector<Group::NodeId>::const_iterator citr = nodeList.begin();
1827             citr != nodeList.end(); ++citr) {
1828            GraphicsObject *node = getGenericGraphicsObject(*citr);
1829            if (node != NULL) {
1830                if (node->getProp())
1831                    _renderer->AddViewProp(node->getProp());
1832                if (node->getOverlayProp())
1833                    _renderer->AddViewProp(node->getOverlayProp());
1834                assert(node == itr->second->removeChild(*citr));
1835            } else {
1836                ERROR("Can't find node: %s", citr->c_str());
1837            }
1838        }
1839     } while (doAll && ++itr != _groups.end());
1840
1841    sceneBoundsChanged();
1842    _needsRedraw = true;
1843}
1844
1845/**
1846 * \brief Create a new HeightMap and associate it with the named DataSet
1847 */
1848bool Renderer::addHeightMap(const DataSetId& id, int numContours, double heightScale)
1849{
1850    DataSetHashmap::iterator itr;
1851
1852    bool doAll = false;
1853
1854    if (id.compare("all") == 0) {
1855        itr = _dataSets.begin();
1856    } else {
1857        itr = _dataSets.find(id);
1858    }
1859    if (itr == _dataSets.end()) {
1860        ERROR("Unknown dataset %s", id.c_str());
1861        return false;
1862    }
1863
1864    do {
1865        DataSet *ds = itr->second;
1866        const DataSetId& dsID = ds->getName();
1867
1868        if (getGraphicsObject<HeightMap>(dsID)) {
1869            WARN("Replacing existing HeightMap %s", dsID.c_str());
1870            deleteGraphicsObject<HeightMap>(dsID);
1871        }
1872
1873        HeightMap *hmap = new HeightMap(numContours, heightScale);
1874
1875        hmap->setDataSet(ds, this);
1876
1877        if (hmap->getProp() == NULL) {
1878            delete hmap;
1879            return false;
1880        } else {
1881            _renderer->AddViewProp(hmap->getProp());
1882        }
1883
1884        _heightMaps[dsID] = hmap;
1885    } while (doAll && ++itr != _dataSets.end());
1886
1887    sceneBoundsChanged();
1888    _needsRedraw = true;
1889    return true;
1890}
1891
1892/**
1893 * \brief Create a new HeightMap and associate it with the named DataSet
1894 */
1895bool Renderer::addHeightMap(const DataSetId& id, const std::vector<double>& contours, double heightScale)
1896{
1897    DataSetHashmap::iterator itr;
1898
1899    bool doAll = false;
1900
1901    if (id.compare("all") == 0) {
1902        itr = _dataSets.begin();
1903    } else {
1904        itr = _dataSets.find(id);
1905    }
1906    if (itr == _dataSets.end()) {
1907        ERROR("Unknown dataset %s", id.c_str());
1908        return false;
1909    }
1910
1911    do {
1912        DataSet *ds = itr->second;
1913        const DataSetId& dsID = ds->getName();
1914
1915        if (getGraphicsObject<HeightMap>(dsID)) {
1916            WARN("Replacing existing HeightMap %s", dsID.c_str());
1917            deleteGraphicsObject<HeightMap>(dsID);
1918        }
1919
1920        HeightMap *hmap = new HeightMap(contours, heightScale);
1921
1922        hmap->setDataSet(ds, this);
1923
1924        if (hmap->getProp() == NULL) {
1925            delete hmap;
1926            return false;
1927        } else {
1928            _renderer->AddViewProp(hmap->getProp());
1929        }
1930
1931        _heightMaps[dsID] = hmap;
1932    } while (doAll && ++itr != _dataSets.end());
1933
1934    sceneBoundsChanged();
1935    _needsRedraw = true;
1936    return true;
1937}
1938
1939/**
1940 * \brief Set amount to scale scalar values when creating elevations
1941 * in the height map
1942 */
1943void Renderer::setHeightMapHeightScale(const DataSetId& id, double scale)
1944{
1945    HeightMapHashmap::iterator itr;
1946
1947    bool doAll = false;
1948
1949    if (id.compare("all") == 0) {
1950        itr = _heightMaps.begin();
1951        if (itr == _heightMaps.end())
1952            return;
1953        doAll = true;
1954    } else {
1955        itr = _heightMaps.find(id);
1956    }
1957
1958    if (itr == _heightMaps.end()) {
1959        ERROR("HeightMap not found: %s", id.c_str());
1960        return;
1961    }
1962
1963    do {
1964        itr->second->setHeightScale(scale);
1965     } while (doAll && ++itr != _heightMaps.end());
1966
1967    sceneBoundsChanged();
1968    _needsRedraw = true;
1969}
1970
1971/**
1972 * \brief Set the point cloud render style for the specified DataSet
1973 */
1974void Renderer::setHeightMapCloudStyle(const DataSetId& id,
1975                                      HeightMap::CloudStyle style)
1976{
1977    HeightMapHashmap::iterator itr;
1978
1979    bool doAll = false;
1980
1981    if (id.compare("all") == 0) {
1982        itr = _heightMaps.begin();
1983        if (itr == _heightMaps.end())
1984            return;
1985        doAll = true;
1986    } else {
1987        itr = _heightMaps.find(id);
1988    }
1989    if (itr == _heightMaps.end()) {
1990        ERROR("HeightMap not found: %s", id.c_str());
1991        return;
1992    }
1993
1994    do {
1995        itr->second->setCloudStyle(style);
1996    } while (doAll && ++itr != _heightMaps.end());
1997
1998    _needsRedraw = true;
1999}
2000
2001/**
2002 * \brief Set the number of equally spaced contour isolines for the given DataSet
2003 */
2004void Renderer::setHeightMapNumContours(const DataSetId& id, int numContours)
2005{
2006    HeightMapHashmap::iterator itr;
2007
2008    bool doAll = false;
2009
2010    if (id.compare("all") == 0) {
2011        itr = _heightMaps.begin();
2012        doAll = true;
2013    } else {
2014        itr = _heightMaps.find(id);
2015    }
2016    if (itr == _heightMaps.end()) {
2017        ERROR("HeightMap not found: %s", id.c_str());
2018        return;
2019    }
2020
2021    do {
2022        itr->second->setNumContours(numContours);
2023    } while (doAll && ++itr != _heightMaps.end());
2024
2025    sceneBoundsChanged();
2026    _needsRedraw = true;
2027}
2028
2029/**
2030 * \brief Set a list of height map contour isovalues for the given DataSet
2031 */
2032void Renderer::setHeightMapContourList(const DataSetId& id, const std::vector<double>& contours)
2033{
2034    HeightMapHashmap::iterator itr;
2035
2036    bool doAll = false;
2037
2038    if (id.compare("all") == 0) {
2039        itr = _heightMaps.begin();
2040        doAll = true;
2041    } else {
2042        itr = _heightMaps.find(id);
2043    }
2044    if (itr == _heightMaps.end()) {
2045        ERROR("HeightMap not found: %s", id.c_str());
2046        return;
2047    }
2048
2049    do {
2050        itr->second->setContourList(contours);
2051    } while (doAll && ++itr != _heightMaps.end());
2052
2053    sceneBoundsChanged();
2054     _needsRedraw = true;
2055}
2056
2057/**
2058 * \brief Turn on/off rendering height map contour lines for the given DataSet
2059 */
2060void Renderer::setHeightMapContourLineVisibility(const DataSetId& id, bool state)
2061{
2062    HeightMapHashmap::iterator itr;
2063
2064    bool doAll = false;
2065
2066    if (id.compare("all") == 0) {
2067        itr = _heightMaps.begin();
2068        if (itr == _heightMaps.end())
2069            return;
2070        doAll = true;
2071    } else {
2072        itr = _heightMaps.find(id);
2073    }
2074    if (itr == _heightMaps.end()) {
2075        ERROR("HeightMap not found: %s", id.c_str());
2076        return;
2077    }
2078
2079    do {
2080        itr->second->setContourLineVisibility(state);
2081    } while (doAll && ++itr != _heightMaps.end());
2082
2083    sceneBoundsChanged();
2084    _needsRedraw = true;
2085}
2086
2087/**
2088 * \brief Turn on/off rendering height map colormap surface for the given DataSet
2089 */
2090void Renderer::setHeightMapContourSurfaceVisibility(const DataSetId& id, bool state)
2091{
2092    HeightMapHashmap::iterator itr;
2093
2094    bool doAll = false;
2095
2096    if (id.compare("all") == 0) {
2097        itr = _heightMaps.begin();
2098        if (itr == _heightMaps.end())
2099            return;
2100        doAll = true;
2101    } else {
2102        itr = _heightMaps.find(id);
2103    }
2104    if (itr == _heightMaps.end()) {
2105        ERROR("HeightMap not found: %s", id.c_str());
2106        return;
2107    }
2108
2109    do {
2110        itr->second->setContourSurfaceVisibility(state);
2111    } while (doAll && ++itr != _heightMaps.end());
2112
2113    sceneBoundsChanged();
2114    _needsRedraw = true;
2115}
2116
2117/**
2118 * \brief Set the RGB height map isoline color for the specified DataSet
2119 */
2120void Renderer::setHeightMapContourEdgeColor(const DataSetId& id, float color[3])
2121{
2122    HeightMapHashmap::iterator itr;
2123
2124    bool doAll = false;
2125
2126    if (id.compare("all") == 0) {
2127        itr = _heightMaps.begin();
2128        if (itr == _heightMaps.end())
2129            return;
2130        doAll = true;
2131    } else {
2132        itr = _heightMaps.find(id);
2133    }
2134    if (itr == _heightMaps.end()) {
2135        ERROR("HeightMap not found: %s", id.c_str());
2136        return;
2137    }
2138
2139    do {
2140        itr->second->setContourEdgeColor(color);
2141    } while (doAll && ++itr != _heightMaps.end());
2142
2143    _needsRedraw = true;
2144}
2145
2146/**
2147 * \brief Set the height map isoline width for the specified DataSet (may be a no-op)
2148 *
2149 * If the OpenGL implementation/hardware does not support wide lines,
2150 * this function may not have an effect.
2151 */
2152void Renderer::setHeightMapContourEdgeWidth(const DataSetId& id, float edgeWidth)
2153{
2154    HeightMapHashmap::iterator itr;
2155
2156    bool doAll = false;
2157
2158    if (id.compare("all") == 0) {
2159        itr = _heightMaps.begin();
2160        if (itr == _heightMaps.end())
2161            return;
2162        doAll = true;
2163    } else {
2164        itr = _heightMaps.find(id);
2165    }
2166    if (itr == _heightMaps.end()) {
2167        ERROR("HeightMap not found: %s", id.c_str());
2168        return;
2169    }
2170
2171    do {
2172        itr->second->setContourEdgeWidth(edgeWidth);
2173    } while (doAll && ++itr != _heightMaps.end());
2174
2175    sceneBoundsChanged();
2176    _needsRedraw = true;
2177}
2178
2179/**
2180 * \brief Toggle colormapping of contour lines
2181 */
2182void Renderer::setHeightMapContourLineColorMapEnabled(const DataSetId& id, bool mode)
2183{
2184    HeightMapHashmap::iterator itr;
2185
2186    bool doAll = false;
2187
2188    if (id.compare("all") == 0) {
2189        itr = _heightMaps.begin();
2190        if (itr == _heightMaps.end())
2191            return;
2192        doAll = true;
2193    } else {
2194        itr = _heightMaps.find(id);
2195    }
2196    if (itr == _heightMaps.end()) {
2197        ERROR("HeightMap not found: %s", id.c_str());
2198        return;
2199    }
2200
2201    do {
2202        itr->second->setContourLineColorMapEnabled(mode);
2203    } while (doAll && ++itr != _heightMaps.end());
2204
2205    _needsRedraw = true;   
2206}
2207
2208/**
2209 * \brief Set the color mode for the specified DataSet
2210 */
2211void Renderer::setHeightMapColorMode(const DataSetId& id,
2212                                     HeightMap::ColorMode mode,
2213                                     DataSet::DataAttributeType type,
2214                                     const char *name, double range[2])
2215{
2216    HeightMapHashmap::iterator itr;
2217
2218    bool doAll = false;
2219
2220    if (id.compare("all") == 0) {
2221        itr = _heightMaps.begin();
2222        if (itr == _heightMaps.end())
2223            return;
2224        doAll = true;
2225    } else {
2226        itr = _heightMaps.find(id);
2227    }
2228    if (itr == _heightMaps.end()) {
2229        ERROR("HeightMap not found: %s", id.c_str());
2230        return;
2231    }
2232
2233    do {
2234        itr->second->setColorMode(mode, type, name, range);
2235    } while (doAll && ++itr != _heightMaps.end());
2236
2237    _needsRedraw = true;
2238}
2239
2240/**
2241 * \brief Set the color mode for the specified DataSet
2242 */
2243void Renderer::setHeightMapColorMode(const DataSetId& id,
2244                                     HeightMap::ColorMode mode,
2245                                     const char *name, double range[2])
2246{
2247    HeightMapHashmap::iterator itr;
2248
2249    bool doAll = false;
2250
2251    if (id.compare("all") == 0) {
2252        itr = _heightMaps.begin();
2253        if (itr == _heightMaps.end())
2254            return;
2255        doAll = true;
2256    } else {
2257        itr = _heightMaps.find(id);
2258    }
2259    if (itr == _heightMaps.end()) {
2260        ERROR("HeightMap not found: %s", id.c_str());
2261        return;
2262    }
2263
2264    do {
2265        itr->second->setColorMode(mode, name, range);
2266    } while (doAll && ++itr != _heightMaps.end());
2267
2268    _needsRedraw = true;
2269}
2270
2271/**
2272 * \brief Create a new Line and associate it with an ID
2273 */
2274bool Renderer::addLine(const DataSetId& id, double pt1[3], double pt2[3])
2275{
2276    Line *gobj;
2277    if ((gobj = getGraphicsObject<Line>(id)) != NULL) {
2278        WARN("Replacing existing %s %s", gobj->getClassName(), id.c_str());
2279        deleteGraphicsObject<Line>(id);
2280    }
2281
2282    gobj = new Line();
2283 
2284    gobj->setDataSet(NULL, this);
2285
2286    if (gobj->getProp() == NULL &&
2287        gobj->getOverlayProp() == NULL) {
2288        delete gobj;
2289        return false;
2290    } else {
2291        if (gobj->getProp())
2292            _renderer->AddViewProp(gobj->getProp());
2293        if (gobj->getOverlayProp())
2294            _renderer->AddViewProp(gobj->getOverlayProp());
2295    }
2296
2297    gobj->setEndPoints(pt1, pt2);
2298
2299    getGraphicsObjectHashmap<Line>()[id] = gobj;
2300
2301    sceneBoundsChanged();
2302    _needsRedraw = true;
2303    return true;
2304}
2305
2306/**
2307 * \brief Create a new Line and associate it with an ID
2308 */
2309bool Renderer::addLine(const DataSetId& id, std::vector<double> points)
2310{
2311    Line *gobj;
2312    if ((gobj = getGraphicsObject<Line>(id)) != NULL) {
2313        WARN("Replacing existing %s %s", gobj->getClassName(), id.c_str());
2314        deleteGraphicsObject<Line>(id);
2315    }
2316
2317    gobj = new Line();
2318 
2319    gobj->setDataSet(NULL, this);
2320
2321    if (gobj->getProp() == NULL &&
2322        gobj->getOverlayProp() == NULL) {
2323        delete gobj;
2324        return false;
2325    } else {
2326        if (gobj->getProp())
2327            _renderer->AddViewProp(gobj->getProp());
2328        if (gobj->getOverlayProp())
2329            _renderer->AddViewProp(gobj->getOverlayProp());
2330    }
2331
2332    gobj->setPoints(points);
2333
2334    getGraphicsObjectHashmap<Line>()[id] = gobj;
2335
2336    sceneBoundsChanged();
2337    _needsRedraw = true;
2338    return true;
2339}
2340
2341/**
2342 * \brief Set atom sphere resolution
2343 */
2344void Renderer::setMoleculeAtomQuality(const DataSetId& id, double quality)
2345{
2346    MoleculeHashmap::iterator itr;
2347
2348    bool doAll = false;
2349
2350    if (id.compare("all") == 0) {
2351        itr = _molecules.begin();
2352        if (itr == _molecules.end())
2353            return;
2354        doAll = true;
2355    } else {
2356        itr = _molecules.find(id);
2357    }
2358    if (itr == _molecules.end()) {
2359        ERROR("Molecule not found: %s", id.c_str());
2360        return;
2361    }
2362
2363    do {
2364        itr->second->setAtomQuality(quality);
2365    } while (doAll && ++itr != _molecules.end());
2366
2367    sceneBoundsChanged();
2368    _needsRedraw = true;
2369}
2370
2371/**
2372 * \brief Set bond cylinder resolution
2373 */
2374void Renderer::setMoleculeBondQuality(const DataSetId& id, double quality)
2375{
2376    MoleculeHashmap::iterator itr;
2377
2378    bool doAll = false;
2379
2380    if (id.compare("all") == 0) {
2381        itr = _molecules.begin();
2382        if (itr == _molecules.end())
2383            return;
2384        doAll = true;
2385    } else {
2386        itr = _molecules.find(id);
2387    }
2388    if (itr == _molecules.end()) {
2389        ERROR("Molecule not found: %s", id.c_str());
2390        return;
2391    }
2392
2393    do {
2394        itr->second->setBondQuality(quality);
2395    } while (doAll && ++itr != _molecules.end());
2396
2397    sceneBoundsChanged();
2398    _needsRedraw = true;
2399}
2400
2401/**
2402 * \brief Set radius scale factor for atoms
2403 */
2404void Renderer::setMoleculeAtomRadiusScale(const DataSetId& id, double scale)
2405{
2406    MoleculeHashmap::iterator itr;
2407
2408    bool doAll = false;
2409
2410    if (id.compare("all") == 0) {
2411        itr = _molecules.begin();
2412        if (itr == _molecules.end())
2413            return;
2414        doAll = true;
2415    } else {
2416        itr = _molecules.find(id);
2417    }
2418    if (itr == _molecules.end()) {
2419        ERROR("Molecule not found: %s", id.c_str());
2420        return;
2421    }
2422
2423    do {
2424        itr->second->setAtomRadiusScale(scale);
2425    } while (doAll && ++itr != _molecules.end());
2426
2427    sceneBoundsChanged();
2428    _needsRedraw = true;
2429}
2430
2431/**
2432 * \brief Set radius standard for scaling atoms
2433 */
2434void Renderer::setMoleculeAtomScaling(const DataSetId& id, Molecule::AtomScaling scaling)
2435{
2436    MoleculeHashmap::iterator itr;
2437
2438    bool doAll = false;
2439
2440    if (id.compare("all") == 0) {
2441        itr = _molecules.begin();
2442        if (itr == _molecules.end())
2443            return;
2444        doAll = true;
2445    } else {
2446        itr = _molecules.find(id);
2447    }
2448    if (itr == _molecules.end()) {
2449        ERROR("Molecule not found: %s", id.c_str());
2450        return;
2451    }
2452
2453    do {
2454        itr->second->setAtomScaling(scaling);
2455    } while (doAll && ++itr != _molecules.end());
2456
2457    sceneBoundsChanged();
2458    _needsRedraw = true;
2459}
2460
2461/**
2462 * \brief Turn on/off rendering of the Molecule atoms for the given DataSet
2463 */
2464void Renderer::setMoleculeAtomVisibility(const DataSetId& id, bool state)
2465{
2466    MoleculeHashmap::iterator itr;
2467
2468    bool doAll = false;
2469
2470    if (id.compare("all") == 0) {
2471        itr = _molecules.begin();
2472        if (itr == _molecules.end())
2473            return;
2474        doAll = true;
2475    } else {
2476        itr = _molecules.find(id);
2477    }
2478    if (itr == _molecules.end()) {
2479        ERROR("Molecule not found: %s", id.c_str());
2480        return;
2481    }
2482
2483    do {
2484        itr->second->setAtomVisibility(state);
2485    } while (doAll && ++itr != _molecules.end());
2486
2487    sceneBoundsChanged();
2488    _needsRedraw = true;
2489}
2490
2491/**
2492 * \brief Set the field used to label atoms for the given DataSet
2493 */
2494void Renderer::setMoleculeAtomLabelField(const DataSetId& id, const char *fieldName)
2495{
2496    MoleculeHashmap::iterator itr;
2497
2498    bool doAll = false;
2499
2500    if (id.compare("all") == 0) {
2501        itr = _molecules.begin();
2502        if (itr == _molecules.end())
2503            return;
2504        doAll = true;
2505    } else {
2506        itr = _molecules.find(id);
2507    }
2508    if (itr == _molecules.end()) {
2509        ERROR("Molecule not found: %s", id.c_str());
2510        return;
2511    }
2512
2513    do {
2514        itr->second->setAtomLabelField(fieldName);
2515    } while (doAll && ++itr != _molecules.end());
2516
2517    _needsRedraw = true;
2518}
2519
2520/**
2521 * \brief Turn on/off rendering of the Molecule atom labels for the given DataSet
2522 */
2523void Renderer::setMoleculeAtomLabelVisibility(const DataSetId& id, bool state)
2524{
2525    MoleculeHashmap::iterator itr;
2526
2527    bool doAll = false;
2528
2529    if (id.compare("all") == 0) {
2530        itr = _molecules.begin();
2531        if (itr == _molecules.end())
2532            return;
2533        doAll = true;
2534    } else {
2535        itr = _molecules.find(id);
2536    }
2537    if (itr == _molecules.end()) {
2538        ERROR("Molecule not found: %s", id.c_str());
2539        return;
2540    }
2541
2542    do {
2543        itr->second->setAtomLabelVisibility(state);
2544    } while (doAll && ++itr != _molecules.end());
2545
2546    sceneBoundsChanged();
2547    _needsRedraw = true;
2548}
2549
2550/**
2551 * \brief Set radius scale factor for atoms
2552 */
2553void Renderer::setMoleculeBondRadiusScale(const DataSetId& id, double scale)
2554{
2555    MoleculeHashmap::iterator itr;
2556
2557    bool doAll = false;
2558
2559    if (id.compare("all") == 0) {
2560        itr = _molecules.begin();
2561        if (itr == _molecules.end())
2562            return;
2563        doAll = true;
2564    } else {
2565        itr = _molecules.find(id);
2566    }
2567    if (itr == _molecules.end()) {
2568        ERROR("Molecule not found: %s", id.c_str());
2569        return;
2570    }
2571
2572    do {
2573        itr->second->setBondRadiusScale(scale);
2574    } while (doAll && ++itr != _molecules.end());
2575
2576    sceneBoundsChanged();
2577    _needsRedraw = true;
2578}
2579
2580/**
2581 * \brief Turn on/off rendering of the Molecule bonds for the given DataSet
2582 */
2583void Renderer::setMoleculeBondVisibility(const DataSetId& id, bool state)
2584{
2585    MoleculeHashmap::iterator itr;
2586
2587    bool doAll = false;
2588
2589    if (id.compare("all") == 0) {
2590        itr = _molecules.begin();
2591        if (itr == _molecules.end())
2592            return;
2593        doAll = true;
2594    } else {
2595        itr = _molecules.find(id);
2596    }
2597    if (itr == _molecules.end()) {
2598        ERROR("Molecule not found: %s", id.c_str());
2599        return;
2600    }
2601
2602    do {
2603        itr->second->setBondVisibility(state);
2604    } while (doAll && ++itr != _molecules.end());
2605
2606    sceneBoundsChanged();
2607    _needsRedraw = true;
2608}
2609
2610/**
2611 * \brief Set render style of the Molecule bonds for the given DataSet
2612 */
2613void Renderer::setMoleculeBondStyle(const DataSetId& id, Molecule::BondStyle style)
2614{
2615    MoleculeHashmap::iterator itr;
2616
2617    bool doAll = false;
2618
2619    if (id.compare("all") == 0) {
2620        itr = _molecules.begin();
2621        if (itr == _molecules.end())
2622            return;
2623        doAll = true;
2624    } else {
2625        itr = _molecules.find(id);
2626    }
2627    if (itr == _molecules.end()) {
2628        ERROR("Molecule not found: %s", id.c_str());
2629        return;
2630    }
2631
2632    do {
2633        itr->second->setBondStyle(style);
2634    } while (doAll && ++itr != _molecules.end());
2635
2636    sceneBoundsChanged();
2637    _needsRedraw = true;
2638}
2639
2640/**
2641 * \brief Set coloring mode of the Molecule bonds for the given DataSet
2642 */
2643void Renderer::setMoleculeBondColorMode(const DataSetId& id, Molecule::BondColorMode mode)
2644{
2645    MoleculeHashmap::iterator itr;
2646
2647    bool doAll = false;
2648
2649    if (id.compare("all") == 0) {
2650        itr = _molecules.begin();
2651        if (itr == _molecules.end())
2652            return;
2653        doAll = true;
2654    } else {
2655        itr = _molecules.find(id);
2656    }
2657    if (itr == _molecules.end()) {
2658        ERROR("Molecule not found: %s", id.c_str());
2659        return;
2660    }
2661
2662    do {
2663        itr->second->setBondColorMode(mode);
2664    } while (doAll && ++itr != _molecules.end());
2665
2666    _needsRedraw = true;
2667}
2668
2669/**
2670 * \brief Set constant color of the Molecule bonds for the given DataSet
2671 */
2672void Renderer::setMoleculeBondColor(const DataSetId& id, float color[3])
2673{
2674    MoleculeHashmap::iterator itr;
2675
2676    bool doAll = false;
2677
2678    if (id.compare("all") == 0) {
2679        itr = _molecules.begin();
2680        if (itr == _molecules.end())
2681            return;
2682        doAll = true;
2683    } else {
2684        itr = _molecules.find(id);
2685    }
2686    if (itr == _molecules.end()) {
2687        ERROR("Molecule not found: %s", id.c_str());
2688        return;
2689    }
2690
2691    do {
2692        itr->second->setBondColor(color);
2693    } while (doAll && ++itr != _molecules.end());
2694
2695    _needsRedraw = true;
2696}
2697
2698/**
2699 * \brief Set the color mode for the specified DataSet
2700 */
2701void Renderer::setMoleculeColorMode(const DataSetId& id,
2702                                    Molecule::ColorMode mode,
2703                                    DataSet::DataAttributeType type,
2704                                    const char *name, double range[2])
2705{
2706    MoleculeHashmap::iterator itr;
2707
2708    bool doAll = false;
2709
2710    if (id.compare("all") == 0) {
2711        itr = _molecules.begin();
2712        if (itr == _molecules.end())
2713            return;
2714        doAll = true;
2715    } else {
2716        itr = _molecules.find(id);
2717    }
2718    if (itr == _molecules.end()) {
2719        ERROR("Molecule not found: %s", id.c_str());
2720        return;
2721    }
2722
2723    do {
2724        itr->second->setColorMode(mode, type, name, range);
2725    } while (doAll && ++itr != _molecules.end());
2726
2727    _needsRedraw = true;
2728}
2729
2730/**
2731 * \brief Set the color mode for the specified DataSet
2732 */
2733void Renderer::setMoleculeColorMode(const DataSetId& id,
2734                                    Molecule::ColorMode mode,
2735                                    const char *name, double range[2])
2736{
2737    MoleculeHashmap::iterator itr;
2738
2739    bool doAll = false;
2740
2741    if (id.compare("all") == 0) {
2742        itr = _molecules.begin();
2743        if (itr == _molecules.end())
2744            return;
2745        doAll = true;
2746    } else {
2747        itr = _molecules.find(id);
2748    }
2749    if (itr == _molecules.end()) {
2750        ERROR("Molecule not found: %s", id.c_str());
2751        return;
2752    }
2753
2754    do {
2755        itr->second->setColorMode(mode, name, range);
2756    } while (doAll && ++itr != _molecules.end());
2757
2758    _needsRedraw = true;
2759}
2760
2761/**
2762 * \brief Create a new n-sided regular Polygon and associate it with an ID
2763 */
2764bool Renderer::addPolygon(const DataSetId& id, int numSides,
2765                          double center[3], double normal[3], double radius)
2766{
2767    Polygon *gobj;
2768    if ((gobj = getGraphicsObject<Polygon>(id)) != NULL) {
2769        WARN("Replacing existing %s %s", gobj->getClassName(), id.c_str());
2770        deleteGraphicsObject<Polygon>(id);
2771    }
2772
2773    gobj = new Polygon();
2774 
2775    gobj->setDataSet(NULL, this);
2776
2777    if (gobj->getProp() == NULL &&
2778        gobj->getOverlayProp() == NULL) {
2779        delete gobj;
2780        return false;
2781    } else {
2782        if (gobj->getProp())
2783            _renderer->AddViewProp(gobj->getProp());
2784        if (gobj->getOverlayProp())
2785            _renderer->AddViewProp(gobj->getOverlayProp());
2786    }
2787
2788    gobj->setNumberOfSides(numSides);
2789    gobj->setCenter(center);
2790    gobj->setNormal(normal);
2791    gobj->setRadius(radius);
2792
2793    getGraphicsObjectHashmap<Polygon>()[id] = gobj;
2794
2795    sceneBoundsChanged();
2796    _needsRedraw = true;
2797    return true;
2798}
2799
2800/**
2801 * \brief Set the  point cloud render style for the specified DataSet
2802 */
2803void Renderer::setPolyDataCloudStyle(const DataSetId& id,
2804                                     PolyData::CloudStyle style)
2805{
2806    PolyDataHashmap::iterator itr;
2807
2808    bool doAll = false;
2809
2810    if (id.compare("all") == 0) {
2811        itr = _polyDatas.begin();
2812        if (itr == _polyDatas.end())
2813            return;
2814        doAll = true;
2815    } else {
2816        itr = _polyDatas.find(id);
2817    }
2818    if (itr == _polyDatas.end()) {
2819        ERROR("PolyData not found: %s", id.c_str());
2820        return;
2821    }
2822
2823    do {
2824        itr->second->setCloudStyle(style);
2825    } while (doAll && ++itr != _polyDatas.end());
2826
2827    _needsRedraw = true;
2828}
2829
2830/**
2831 * \brief Set the  point cloud render style for the specified DataSet
2832 */
2833void Renderer::setPseudoColorCloudStyle(const DataSetId& id,
2834                                        PseudoColor::CloudStyle style)
2835{
2836    PseudoColorHashmap::iterator itr;
2837
2838    bool doAll = false;
2839
2840    if (id.compare("all") == 0) {
2841        itr = _pseudoColors.begin();
2842        if (itr == _pseudoColors.end())
2843            return;
2844        doAll = true;
2845    } else {
2846        itr = _pseudoColors.find(id);
2847    }
2848    if (itr == _pseudoColors.end()) {
2849        ERROR("PseudoColor not found: %s", id.c_str());
2850        return;
2851    }
2852
2853    do {
2854        itr->second->setCloudStyle(style);
2855    } while (doAll && ++itr != _pseudoColors.end());
2856
2857    _needsRedraw = true;
2858}
2859
2860/**
2861 * \brief Set the color mode for the specified DataSet
2862 */
2863void Renderer::setPseudoColorColorMode(const DataSetId& id,
2864                                       PseudoColor::ColorMode mode,
2865                                       DataSet::DataAttributeType type,
2866                                       const char *name, double range[2])
2867{
2868    PseudoColorHashmap::iterator itr;
2869
2870    bool doAll = false;
2871
2872    if (id.compare("all") == 0) {
2873        itr = _pseudoColors.begin();
2874        if (itr == _pseudoColors.end())
2875            return;
2876        doAll = true;
2877    } else {
2878        itr = _pseudoColors.find(id);
2879    }
2880    if (itr == _pseudoColors.end()) {
2881        ERROR("PseudoColor not found: %s", id.c_str());
2882        return;
2883    }
2884
2885    do {
2886        itr->second->setColorMode(mode, type, name, range);
2887    } while (doAll && ++itr != _pseudoColors.end());
2888
2889    _needsRedraw = true;
2890}
2891
2892/**
2893 * \brief Set the color mode for the specified DataSet
2894 */
2895void Renderer::setPseudoColorColorMode(const DataSetId& id,
2896                                       PseudoColor::ColorMode mode,
2897                                       const char *name, double range[2])
2898{
2899    PseudoColorHashmap::iterator itr;
2900
2901    bool doAll = false;
2902
2903    if (id.compare("all") == 0) {
2904        itr = _pseudoColors.begin();
2905        if (itr == _pseudoColors.end())
2906            return;
2907        doAll = true;
2908    } else {
2909        itr = _pseudoColors.find(id);
2910    }
2911    if (itr == _pseudoColors.end()) {
2912        ERROR("PseudoColor not found: %s", id.c_str());
2913        return;
2914    }
2915
2916    do {
2917        itr->second->setColorMode(mode, name, range);
2918    } while (doAll && ++itr != _pseudoColors.end());
2919
2920    _needsRedraw = true;
2921}
2922
2923/**
2924 * \brief Create a new Sphere and associate it with an ID
2925 */
2926bool Renderer::addSphere(const DataSetId& id, double center[3], double radius, bool flipNormals)
2927{
2928    Sphere *gobj;
2929    if ((gobj = getGraphicsObject<Sphere>(id)) != NULL) {
2930        WARN("Replacing existing %s %s", gobj->getClassName(), id.c_str());
2931        deleteGraphicsObject<Sphere>(id);
2932    }
2933
2934    gobj = new Sphere();
2935 
2936    gobj->setDataSet(NULL, this);
2937
2938    if (gobj->getProp() == NULL &&
2939        gobj->getOverlayProp() == NULL) {
2940        delete gobj;
2941        return false;
2942    } else {
2943        if (gobj->getProp())
2944            _renderer->AddViewProp(gobj->getProp());
2945        if (gobj->getOverlayProp())
2946            _renderer->AddViewProp(gobj->getOverlayProp());
2947    }
2948
2949    gobj->setCenter(center);
2950    gobj->setRadius(radius);
2951    if (flipNormals)
2952        gobj->flipNormals(flipNormals);
2953
2954    getGraphicsObjectHashmap<Sphere>()[id] = gobj;
2955
2956    sceneBoundsChanged();
2957    _needsRedraw = true;
2958    return true;
2959}
2960
2961/**
2962 * \brief Set Sphere resolution
2963 */
2964void Renderer::setSphereResolution(const DataSetId& id, int thetaRes, int phiRes)
2965{
2966    SphereHashmap::iterator itr;
2967
2968    bool doAll = false;
2969
2970    if (id.compare("all") == 0) {
2971        itr = _spheres.begin();
2972        if (itr == _spheres.end())
2973            return;
2974        doAll = true;
2975    } else {
2976        itr = _spheres.find(id);
2977    }
2978    if (itr == _spheres.end()) {
2979        ERROR("Sphere not found: %s", id.c_str());
2980        return;
2981    }
2982
2983    do {
2984        itr->second->setThetaResolution(thetaRes);
2985        itr->second->setPhiResolution(phiRes);
2986    } while (doAll && ++itr != _spheres.end());
2987
2988    sceneBoundsChanged();
2989    _needsRedraw = true;
2990}
2991
2992/**
2993 * \brief Set Sphere section
2994 */
2995void Renderer::setSphereSection(const DataSetId& id, double thetaStart, double thetaEnd,
2996                                double phiStart, double phiEnd)
2997{
2998    SphereHashmap::iterator itr;
2999
3000    bool doAll = false;
3001
3002    if (id.compare("all") == 0) {
3003        itr = _spheres.begin();
3004        if (itr == _spheres.end())
3005            return;
3006        doAll = true;
3007    } else {
3008        itr = _spheres.find(id);
3009    }
3010    if (itr == _spheres.end()) {
3011        ERROR("Sphere not found: %s", id.c_str());
3012        return;
3013    }
3014
3015    do {
3016        itr->second->setStartTheta(thetaStart);
3017        itr->second->setEndTheta(thetaEnd);
3018        itr->second->setStartPhi(phiStart);
3019        itr->second->setEndPhi(phiEnd);
3020    } while (doAll && ++itr != _spheres.end());
3021
3022    sceneBoundsChanged();
3023    _needsRedraw = true;
3024}
3025
3026/**
3027 * \brief Set the streamlines seed to points of the streamlines DataSet
3028 */
3029void Renderer::setStreamlinesNumberOfSeedPoints(const DataSetId& id, int numPoints)
3030{
3031    StreamlinesHashmap::iterator itr;
3032
3033    bool doAll = false;
3034
3035    if (id.compare("all") == 0) {
3036        itr = _streamlines.begin();
3037        if (itr == _streamlines.end())
3038            return;
3039        doAll = true;
3040    } else {
3041        itr = _streamlines.find(id);
3042    }
3043    if (itr == _streamlines.end()) {
3044        ERROR("Streamlines not found: %s", id.c_str());
3045        return;
3046    }
3047
3048    do {
3049        itr->second->setNumberOfSeedPoints(numPoints);
3050    } while (doAll && ++itr != _streamlines.end());
3051
3052    sceneBoundsChanged();
3053    _needsRedraw = true;
3054}
3055
3056/**
3057 * \brief Set the streamlines seed point size (may be a no-op)
3058 */
3059void Renderer::setStreamlinesSeedPointSize(const DataSetId& id, float size)
3060{
3061    StreamlinesHashmap::iterator itr;
3062
3063    bool doAll = false;
3064
3065    if (id.compare("all") == 0) {
3066        itr = _streamlines.begin();
3067        if (itr == _streamlines.end())
3068            return;
3069        doAll = true;
3070    } else {
3071        itr = _streamlines.find(id);
3072    }
3073    if (itr == _streamlines.end()) {
3074        ERROR("Streamlines not found: %s", id.c_str());
3075        return;
3076    }
3077
3078    do {
3079        itr->second->setSeedPointSize(size);
3080    } while (doAll && ++itr != _streamlines.end());
3081
3082    _needsRedraw = true;
3083}
3084
3085/**
3086 * \brief Set the streamlines seed to points of the streamlines DataSet
3087 */
3088void Renderer::setStreamlinesSeedToMeshPoints(const DataSetId& id,
3089                                              int maxPoints)
3090{
3091    StreamlinesHashmap::iterator itr;
3092
3093    bool doAll = false;
3094
3095    if (id.compare("all") == 0) {
3096        itr = _streamlines.begin();
3097        if (itr == _streamlines.end())
3098            return;
3099        doAll = true;
3100    } else {
3101        itr = _streamlines.find(id);
3102    }
3103    if (itr == _streamlines.end()) {
3104        ERROR("Streamlines not found: %s", id.c_str());
3105        return;
3106    }
3107
3108    do {
3109        itr->second->setSeedToMeshPoints(maxPoints);
3110    } while (doAll && ++itr != _streamlines.end());
3111
3112    sceneBoundsChanged();
3113    _needsRedraw = true;
3114}
3115
3116/**
3117 * \brief Set the streamlines seed to points distributed randomly inside
3118 * cells of the streamlines DataSet
3119 */
3120void Renderer::setStreamlinesSeedToFilledMesh(const DataSetId& id, int numPoints)
3121{
3122    StreamlinesHashmap::iterator itr;
3123
3124    bool doAll = false;
3125
3126    if (id.compare("all") == 0) {
3127        itr = _streamlines.begin();
3128        if (itr == _streamlines.end())
3129            return;
3130        doAll = true;
3131    } else {
3132        itr = _streamlines.find(id);
3133    }
3134    if (itr == _streamlines.end()) {
3135        ERROR("Streamlines not found: %s", id.c_str());
3136        return;
3137    }
3138
3139    do {
3140        itr->second->setSeedToFilledMesh(numPoints);
3141    } while (doAll && ++itr != _streamlines.end());
3142
3143    sceneBoundsChanged();
3144    _needsRedraw = true;
3145}
3146
3147/**
3148 * \brief Set the streamlines seed to points of a DataSet
3149 *
3150 * \param[in] id DataSet identifier
3151 * \param[in] data Bytes of VTK DataSet file
3152 * \param[in] nbytes Length of data array
3153 * \param[in] maxPoints Maximum number of points to be used as seeds
3154 *
3155 * \return boolean indicating success or failure
3156 */
3157bool Renderer::setStreamlinesSeedToMeshPoints(const DataSetId& id,
3158                                              char *data, size_t nbytes,
3159                                              int maxPoints)
3160{
3161    vtkSmartPointer<vtkDataSetReader> reader = vtkSmartPointer<vtkDataSetReader>::New();
3162    vtkSmartPointer<vtkCharArray> dataSetString = vtkSmartPointer<vtkCharArray>::New();
3163
3164    dataSetString->SetArray(data, nbytes, 1);
3165    reader->SetInputArray(dataSetString);
3166    reader->ReadFromInputStringOn();
3167    reader->Update();
3168
3169    vtkSmartPointer<vtkDataSet> dataSet = reader->GetOutput();
3170    if (dataSet == NULL) {
3171        return false;
3172    }
3173#ifndef USE_VTK6
3174    dataSet->SetPipelineInformation(NULL);
3175#endif
3176    StreamlinesHashmap::iterator itr;
3177
3178    bool doAll = false;
3179
3180    if (id.compare("all") == 0) {
3181        itr = _streamlines.begin();
3182        doAll = true;
3183    } else {
3184        itr = _streamlines.find(id);
3185    }
3186    if (itr == _streamlines.end()) {
3187        ERROR("Streamlines not found: %s", id.c_str());
3188        return false;
3189    }
3190
3191    do {
3192        itr->second->setSeedToMeshPoints(dataSet, maxPoints);
3193    } while (doAll && ++itr != _streamlines.end());
3194
3195    sceneBoundsChanged();
3196    _needsRedraw = true;
3197    return true;
3198}
3199
3200/**
3201 * \brief Set the streamlines seed to points distributed randomly inside
3202 * cells of DataSet
3203 *
3204 * \param[in] id DataSet identifier
3205 * \param[in] data Bytes of VTK DataSet file
3206 * \param[in] nbytes Length of data array
3207 * \param[in] numPoints Number of random seed points to generate
3208 *
3209 * \return boolean indicating success or failure
3210 */
3211bool Renderer::setStreamlinesSeedToFilledMesh(const DataSetId& id,
3212                                              char *data, size_t nbytes,
3213                                              int numPoints)
3214{
3215    vtkSmartPointer<vtkDataSetReader> reader = vtkSmartPointer<vtkDataSetReader>::New();
3216    vtkSmartPointer<vtkCharArray> dataSetString = vtkSmartPointer<vtkCharArray>::New();
3217
3218    dataSetString->SetArray(data, nbytes, 1);
3219    reader->SetInputArray(dataSetString);
3220    reader->ReadFromInputStringOn();
3221    reader->Update();
3222
3223    vtkSmartPointer<vtkDataSet> dataSet = reader->GetOutput();
3224    if (dataSet == NULL) {
3225        return false;
3226    }
3227#ifndef USE_VTK6
3228    dataSet->SetPipelineInformation(NULL);
3229#endif
3230    StreamlinesHashmap::iterator itr;
3231
3232    bool doAll = false;
3233
3234    if (id.compare("all") == 0) {
3235        itr = _streamlines.begin();
3236        doAll = true;
3237    } else {
3238        itr = _streamlines.find(id);
3239    }
3240    if (itr == _streamlines.end()) {
3241        ERROR("Streamlines not found: %s", id.c_str());
3242        return false;
3243    }
3244
3245    do {
3246        itr->second->setSeedToFilledMesh(dataSet, numPoints);
3247    } while (doAll && ++itr != _streamlines.end());
3248
3249    sceneBoundsChanged();
3250    _needsRedraw = true;
3251    return true;
3252}
3253
3254/**
3255 * \brief Set the streamlines seed to points along a line
3256 */
3257void Renderer::setStreamlinesSeedToRake(const DataSetId& id,
3258                                        double start[3], double end[3],
3259                                        int numPoints)
3260{
3261    StreamlinesHashmap::iterator itr;
3262
3263    bool doAll = false;
3264
3265    if (id.compare("all") == 0) {
3266        itr = _streamlines.begin();
3267        if (itr == _streamlines.end())
3268            return;
3269        doAll = true;
3270    } else {
3271        itr = _streamlines.find(id);
3272    }
3273    if (itr == _streamlines.end()) {
3274        ERROR("Streamlines not found: %s", id.c_str());
3275        return;
3276    }
3277
3278    do {
3279        itr->second->setSeedToRake(start, end, numPoints);
3280    } while (doAll && ++itr != _streamlines.end());
3281
3282    sceneBoundsChanged();
3283    _needsRedraw = true;
3284}
3285
3286/**
3287 * \brief Set the streamlines seed to points inside a disk, with optional
3288 * hole
3289 */
3290void Renderer::setStreamlinesSeedToDisk(const DataSetId& id,
3291                                        double center[3], double normal[3],
3292                                        double radius, double innerRadius,
3293                                        int numPoints)
3294{
3295    StreamlinesHashmap::iterator itr;
3296
3297    bool doAll = false;
3298
3299    if (id.compare("all") == 0) {
3300        itr = _streamlines.begin();
3301        if (itr == _streamlines.end())
3302            return;
3303        doAll = true;
3304    } else {
3305        itr = _streamlines.find(id);
3306    }
3307    if (itr == _streamlines.end()) {
3308        ERROR("Streamlines not found: %s", id.c_str());
3309        return;
3310    }
3311
3312    do {
3313        itr->second->setSeedToDisk(center, normal, radius, innerRadius, numPoints);
3314    } while (doAll && ++itr != _streamlines.end());
3315
3316    sceneBoundsChanged();
3317    _needsRedraw = true;
3318}
3319
3320/**
3321 * \brief Set the streamlines seed to vertices of an n-sided polygon
3322 */
3323void Renderer::setStreamlinesSeedToPolygon(const DataSetId& id,
3324                                           double center[3], double normal[3],
3325                                           double angle, double radius,
3326                                           int numSides)
3327{
3328    StreamlinesHashmap::iterator itr;
3329
3330    bool doAll = false;
3331
3332    if (id.compare("all") == 0) {
3333        itr = _streamlines.begin();
3334        if (itr == _streamlines.end())
3335            return;
3336        doAll = true;
3337    } else {
3338        itr = _streamlines.find(id);
3339    }
3340    if (itr == _streamlines.end()) {
3341        ERROR("Streamlines not found: %s", id.c_str());
3342        return;
3343    }
3344
3345    do {
3346        itr->second->setSeedToPolygon(center, normal, angle, radius, numSides);
3347    } while (doAll && ++itr != _streamlines.end());
3348
3349    sceneBoundsChanged();
3350    _needsRedraw = true;
3351}
3352
3353/**
3354 * \brief Set the streamlines seed to vertices of an n-sided polygon
3355 */
3356void Renderer::setStreamlinesSeedToFilledPolygon(const DataSetId& id,
3357                                                 double center[3],
3358                                                 double normal[3],
3359                                                 double angle, double radius,
3360                                                 int numSides, int numPoints)
3361{
3362    StreamlinesHashmap::iterator itr;
3363
3364    bool doAll = false;
3365
3366    if (id.compare("all") == 0) {
3367        itr = _streamlines.begin();
3368        if (itr == _streamlines.end())
3369            return;
3370        doAll = true;
3371    } else {
3372        itr = _streamlines.find(id);
3373    }
3374    if (itr == _streamlines.end()) {
3375        ERROR("Streamlines not found: %s", id.c_str());
3376        return;
3377    }
3378
3379    do {
3380        itr->second->setSeedToFilledPolygon(center, normal, angle,
3381                                            radius, numSides, numPoints);
3382    } while (doAll && ++itr != _streamlines.end());
3383
3384    sceneBoundsChanged();
3385    _needsRedraw = true;
3386}
3387
3388void Renderer::setStreamlinesTerminalSpeed(const DataSetId& id, double speed)
3389{
3390    StreamlinesHashmap::iterator itr;
3391
3392    bool doAll = false;
3393
3394    if (id.compare("all") == 0) {
3395        itr = _streamlines.begin();
3396        if (itr == _streamlines.end())
3397            return;
3398        doAll = true;
3399    } else {
3400        itr = _streamlines.find(id);
3401    }
3402    if (itr == _streamlines.end()) {
3403        ERROR("Streamlines not found: %s", id.c_str());
3404        return;
3405    }
3406
3407    do {
3408        itr->second->setTerminalSpeed(speed);
3409    } while (doAll && ++itr != _streamlines.end());
3410
3411    sceneBoundsChanged();
3412    _needsRedraw = true;
3413}
3414
3415/**
3416 * \brief Set Streamlines rendering to polylines for the specified DataSet
3417 */
3418void Renderer::setStreamlinesTypeToLines(const DataSetId& id)
3419{
3420    StreamlinesHashmap::iterator itr;
3421
3422    bool doAll = false;
3423
3424    if (id.compare("all") == 0) {
3425        itr = _streamlines.begin();
3426        if (itr == _streamlines.end())
3427            return;
3428        doAll = true;
3429    } else {
3430        itr = _streamlines.find(id);
3431    }
3432    if (itr == _streamlines.end()) {
3433        ERROR("Streamlines not found: %s", id.c_str());
3434        return;
3435    }
3436
3437    do {
3438        itr->second->setLineTypeToLines();
3439    } while (doAll && ++itr != _streamlines.end());
3440
3441    sceneBoundsChanged();
3442    _needsRedraw = true;
3443}
3444
3445/**
3446 * \brief Set Streamlines rendering to tubes for the specified DataSet
3447 */
3448void Renderer::setStreamlinesTypeToTubes(const DataSetId& id, int numSides, double radius)
3449{
3450    StreamlinesHashmap::iterator itr;
3451
3452    bool doAll = false;
3453
3454    if (id.compare("all") == 0) {
3455        itr = _streamlines.begin();
3456        if (itr == _streamlines.end())
3457            return;
3458        doAll = true;
3459    } else {
3460        itr = _streamlines.find(id);
3461    }
3462    if (itr == _streamlines.end()) {
3463        ERROR("Streamlines not found: %s", id.c_str());
3464        return;
3465    }
3466
3467    do {
3468        itr->second->setLineTypeToTubes(numSides, radius);
3469    } while (doAll && ++itr != _streamlines.end());
3470
3471    sceneBoundsChanged();
3472    _needsRedraw = true;
3473}
3474
3475/**
3476 * \brief Set Streamlines rendering to ribbons for the specified DataSet
3477 */
3478void Renderer::setStreamlinesTypeToRibbons(const DataSetId& id, double width, double angle)
3479{
3480    StreamlinesHashmap::iterator itr;
3481
3482    bool doAll = false;
3483
3484    if (id.compare("all") == 0) {
3485        itr = _streamlines.begin();
3486        if (itr == _streamlines.end())
3487            return;
3488        doAll = true;
3489    } else {
3490        itr = _streamlines.find(id);
3491    }
3492    if (itr == _streamlines.end()) {
3493        ERROR("Streamlines not found: %s", id.c_str());
3494        return;
3495    }
3496
3497    do {
3498        itr->second->setLineTypeToRibbons(width, angle);
3499    } while (doAll && ++itr != _streamlines.end());
3500
3501    sceneBoundsChanged();
3502    _needsRedraw = true;
3503}
3504
3505/**
3506 * \brief Set Streamlines maximum length for the specified DataSet
3507 */
3508void Renderer::setStreamlinesLength(const DataSetId& id, double length)
3509{
3510    StreamlinesHashmap::iterator itr;
3511
3512    bool doAll = false;
3513
3514    if (id.compare("all") == 0) {
3515        itr = _streamlines.begin();
3516        if (itr == _streamlines.end())
3517            return;
3518        doAll = true;
3519    } else {
3520        itr = _streamlines.find(id);
3521    }
3522    if (itr == _streamlines.end()) {
3523        ERROR("Streamlines not found: %s", id.c_str());
3524        return;
3525    }
3526
3527    do {
3528        itr->second->setMaxPropagation(length);
3529    } while (doAll && ++itr != _streamlines.end());
3530
3531    sceneBoundsChanged();
3532    _needsRedraw = true;
3533}
3534
3535/**
3536 * \brief Turn on/off rendering of the Streamlines seed geometry for the given DataSet
3537 */
3538void Renderer::setStreamlinesSeedVisibility(const DataSetId& id, bool state)
3539{
3540    StreamlinesHashmap::iterator itr;
3541
3542    bool doAll = false;
3543
3544    if (id.compare("all") == 0) {
3545        itr = _streamlines.begin();
3546        if (itr == _streamlines.end())
3547            return;
3548        doAll = true;
3549    } else {
3550        itr = _streamlines.find(id);
3551    }
3552    if (itr == _streamlines.end()) {
3553        ERROR("Streamlines not found: %s", id.c_str());
3554        return;
3555    }
3556
3557    do {
3558        itr->second->setSeedVisibility(state);
3559    } while (doAll && ++itr != _streamlines.end());
3560
3561    sceneBoundsChanged();
3562    _needsRedraw = true;
3563}
3564
3565/**
3566 * \brief Set the color mode for the specified DataSet
3567 */
3568void Renderer::setStreamlinesColorMode(const DataSetId& id,
3569                                       Streamlines::ColorMode mode,
3570                                       DataSet::DataAttributeType type,
3571                                       const char *name, double range[2])
3572{
3573    StreamlinesHashmap::iterator itr;
3574
3575    bool doAll = false;
3576
3577    if (id.compare("all") == 0) {
3578        itr = _streamlines.begin();
3579        if (itr == _streamlines.end())
3580            return;
3581        doAll = true;
3582    } else {
3583        itr = _streamlines.find(id);
3584    }
3585    if (itr == _streamlines.end()) {
3586        ERROR("Streamlines not found: %s", id.c_str());
3587        return;
3588    }
3589
3590    do {
3591        itr->second->setColorMode(mode, type, name, range);
3592    } while (doAll && ++itr != _streamlines.end());
3593
3594    _needsRedraw = true;
3595}
3596
3597/**
3598 * \brief Set the color mode for the specified DataSet
3599 */
3600void Renderer::setStreamlinesColorMode(const DataSetId& id,
3601                                       Streamlines::ColorMode mode,
3602                                       const char *name, double range[2])
3603{
3604    StreamlinesHashmap::iterator itr;
3605
3606    bool doAll = false;
3607
3608    if (id.compare("all") == 0) {
3609        itr = _streamlines.begin();
3610        if (itr == _streamlines.end())
3611            return;
3612        doAll = true;
3613    } else {
3614        itr = _streamlines.find(id);
3615    }
3616    if (itr == _streamlines.end()) {
3617        ERROR("Streamlines not found: %s", id.c_str());
3618        return;
3619    }
3620
3621    do {
3622        itr->second->setColorMode(mode, name, range);
3623    } while (doAll && ++itr != _streamlines.end());
3624
3625    _needsRedraw = true;
3626}
3627
3628/**
3629 * \brief Set the RGB line/edge color for the specified DataSet
3630 */
3631void Renderer::setStreamlinesSeedColor(const DataSetId& id, float color[3])
3632{
3633    StreamlinesHashmap::iterator itr;
3634
3635    bool doAll = false;
3636
3637    if (id.compare("all") == 0) {
3638        itr = _streamlines.begin();
3639        if (itr == _streamlines.end())
3640            return;
3641        doAll = true;
3642    } else {
3643        itr = _streamlines.find(id);
3644    }
3645    if (itr == _streamlines.end()) {
3646        ERROR("Streamlines not found: %s", id.c_str());
3647        return;
3648    }
3649
3650    do {
3651        itr->second->setSeedColor(color);
3652    } while (doAll && ++itr != _streamlines.end());
3653
3654    _needsRedraw = true;
3655}
3656
3657/**
3658 * \brief Set the sample rate for the volume shader
3659 *
3660 * Smaller values will give better rendering at the cost
3661 * of slower rendering
3662 */
3663void Renderer::setVolumeSampleDistance(const DataSetId& id, double distance)
3664{
3665    VolumeHashmap::iterator itr;
3666
3667    bool doAll = false;
3668
3669    if (id.compare("all") == 0) {
3670        itr = _volumes.begin();
3671        if (itr == _volumes.end())
3672            return;
3673        doAll = true;
3674    } else {
3675        itr = _volumes.find(id);
3676    }
3677    if (itr == _volumes.end()) {
3678        ERROR("Volume not found: %s", id.c_str());
3679        return;
3680    }
3681
3682    do {
3683        distance *= itr->second->getAverageSpacing();
3684        itr->second->setSampleDistance((float)distance);
3685    } while (doAll && ++itr != _volumes.end());
3686
3687    _needsRedraw = true;
3688}
3689
3690/**
3691 * \brief Set the point cloud render style for the specified DataSet
3692 */
3693void Renderer::setWarpCloudStyle(const DataSetId& id,
3694                                 Warp::CloudStyle style)
3695{
3696    WarpHashmap::iterator itr;
3697
3698    bool doAll = false;
3699
3700    if (id.compare("all") == 0) {
3701        itr = _warps.begin();
3702        if (itr == _warps.end())
3703            return;
3704        doAll = true;
3705    } else {
3706        itr = _warps.find(id);
3707    }
3708    if (itr == _warps.end()) {
3709        ERROR("Warp not found: %s", id.c_str());
3710        return;
3711    }
3712
3713    do {
3714        itr->second->setCloudStyle(style);
3715    } while (doAll && ++itr != _warps.end());
3716
3717    _needsRedraw = true;
3718}
3719
3720/**
3721 * \brief Set the color mode for the specified DataSet
3722 */
3723void Renderer::setWarpColorMode(const DataSetId& id,
3724                                Warp::ColorMode mode,
3725                                DataSet::DataAttributeType type,
3726                                const char *name, double range[2])
3727{
3728    WarpHashmap::iterator itr;
3729
3730    bool doAll = false;
3731
3732    if (id.compare("all") == 0) {
3733        itr = _warps.begin();
3734        if (itr == _warps.end())
3735            return;
3736        doAll = true;
3737    } else {
3738        itr = _warps.find(id);
3739    }
3740    if (itr == _warps.end()) {
3741        ERROR("Warp not found: %s", id.c_str());
3742        return;
3743    }
3744
3745    do {
3746        itr->second->setColorMode(mode, type, name, range);
3747    } while (doAll && ++itr != _warps.end());
3748
3749    _needsRedraw = true;
3750}
3751
3752/**
3753 * \brief Set the color mode for the specified DataSet
3754 */
3755void Renderer::setWarpColorMode(const DataSetId& id,
3756                                Warp::ColorMode mode,
3757                                const char *name, double range[2])
3758{
3759    WarpHashmap::iterator itr;
3760
3761    bool doAll = false;
3762
3763    if (id.compare("all") == 0) {
3764        itr = _warps.begin();
3765        if (itr == _warps.end())
3766            return;
3767        doAll = true;
3768    } else {
3769        itr = _warps.find(id);
3770    }
3771    if (itr == _warps.end()) {
3772        ERROR("Warp not found: %s", id.c_str());
3773        return;
3774    }
3775
3776    do {
3777        itr->second->setColorMode(mode, name, range);
3778    } while (doAll && ++itr != _warps.end());
3779
3780    _needsRedraw = true;
3781}
3782
3783/**
3784 * \brief Set amount to scale vector magnitudes when warping
3785 * a mesh
3786 */
3787void Renderer::setWarpWarpScale(const DataSetId& id, double scale)
3788{
3789    WarpHashmap::iterator itr;
3790
3791    bool doAll = false;
3792
3793    if (id.compare("all") == 0) {
3794        itr = _warps.begin();
3795        if (itr == _warps.end())
3796            return;
3797        doAll = true;
3798    } else {
3799        itr = _warps.find(id);
3800    }
3801
3802    if (itr == _warps.end()) {
3803        ERROR("Warp not found: %s", id.c_str());
3804        return;
3805    }
3806
3807    do {
3808        itr->second->setWarpScale(scale);
3809     } while (doAll && ++itr != _warps.end());
3810
3811    sceneBoundsChanged();
3812    _needsRedraw = true;
3813}
Note: See TracBrowser for help on using the repository browser.