source: branches/nanovis2/packages/vizservers/vtkvis/RpVtkRendererGraphicsObjs.cpp @ 3305

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

sync with trunk

  • Property svn:eol-style set to native
File size: 62.9 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
11#include <vtkVersion.h>
12#if (VTK_MAJOR_VERSION >= 6)
13#define USE_VTK6
14#endif
15#include <vtkSmartPointer.h>
16#include <vtkDataSet.h>
17#include <vtkCharArray.h>
18#include <vtkDataSetReader.h>
19
20#include "RpVtkRendererGraphicsObjs.h"
21#include "RpVtkRenderer.h"
22#include "RpVtkDataSet.h"
23#include "RpBox.h"
24#include "RpContour2D.h"
25#include "RpContour3D.h"
26#include "RpCutplane.h"
27#include "RpGlyphs.h"
28#include "RpHeightMap.h"
29#include "RpLIC.h"
30#include "RpLine.h"
31#include "RpMolecule.h"
32#include "RpPolyData.h"
33#include "RpPseudoColor.h"
34#include "RpSphere.h"
35#include "RpStreamlines.h"
36#include "RpVolume.h"
37#include "ColorMap.h"
38#include "Trace.h"
39
40// Template specializations
41namespace Rappture {
42namespace VtkVis {
43
44template<>
45Renderer::ArcHashmap &
46Renderer::getGraphicsObjectHashmap<Arc>()
47{ return _arcs; }
48
49template<>
50Renderer::ArrowHashmap &
51Renderer::getGraphicsObjectHashmap<Arrow>()
52{ return _arrows; }
53
54template<>
55Renderer::BoxHashmap &
56Renderer::getGraphicsObjectHashmap<Box>()
57{ return _boxes; }
58
59template<>
60Renderer::ConeHashmap &
61Renderer::getGraphicsObjectHashmap<Cone>()
62{ return _cones; }
63
64template<>
65Renderer::Contour2DHashmap &
66Renderer::getGraphicsObjectHashmap<Contour2D>()
67{ return _contour2Ds; }
68
69template<>
70Renderer::Contour3DHashmap &
71Renderer::getGraphicsObjectHashmap<Contour3D>()
72{ return _contour3Ds; }
73
74template<>
75Renderer::CutplaneHashmap &
76Renderer::getGraphicsObjectHashmap<Cutplane>()
77{ return _cutplanes; }
78
79template<>
80Renderer::CylinderHashmap &
81Renderer::getGraphicsObjectHashmap<Cylinder>()
82{ return _cylinders; }
83
84template<>
85Renderer::DiskHashmap &
86Renderer::getGraphicsObjectHashmap<Disk>()
87{ return _disks; }
88
89template<>
90Renderer::GlyphsHashmap &
91Renderer::getGraphicsObjectHashmap<Glyphs>()
92{ return _glyphs; }
93
94template<>
95Renderer::GroupHashmap &
96Renderer::getGraphicsObjectHashmap<Group>()
97{ return _groups; }
98
99template<>
100Renderer::HeightMapHashmap &
101Renderer::getGraphicsObjectHashmap<HeightMap>()
102{ return _heightMaps; }
103
104template<>
105Renderer::LICHashmap &
106Renderer::getGraphicsObjectHashmap<LIC>()
107{ return _lics; }
108
109template<>
110Renderer::LineHashmap &
111Renderer::getGraphicsObjectHashmap<Line>()
112{ return _lines; }
113
114template<>
115Renderer::MoleculeHashmap &
116Renderer::getGraphicsObjectHashmap<Molecule>()
117{ return _molecules; }
118
119template<>
120Renderer::PolyDataHashmap &
121Renderer::getGraphicsObjectHashmap<PolyData>()
122{ return _polyDatas; }
123
124template<>
125Renderer::PolygonHashmap &
126Renderer::getGraphicsObjectHashmap<Polygon>()
127{ return _polygons; }
128
129template<>
130Renderer::PseudoColorHashmap &
131Renderer::getGraphicsObjectHashmap<PseudoColor>()
132{ return _pseudoColors; }
133
134template<>
135Renderer::SphereHashmap &
136Renderer::getGraphicsObjectHashmap<Sphere>()
137{ return _spheres; }
138
139template<>
140Renderer::StreamlinesHashmap &
141Renderer::getGraphicsObjectHashmap<Streamlines>()
142{ return _streamlines; }
143
144template<>
145Renderer::VolumeHashmap &
146Renderer::getGraphicsObjectHashmap<Volume>()
147{ return _volumes; }
148
149template<>
150Renderer::WarpHashmap &
151Renderer::getGraphicsObjectHashmap<Warp>()
152{ return _warps; }
153
154template Arc *Renderer::getGraphicsObject(const DataSetId&);
155template Arrow *Renderer::getGraphicsObject(const DataSetId&);
156template Box *Renderer::getGraphicsObject(const DataSetId&);
157template Cone *Renderer::getGraphicsObject(const DataSetId&);
158template Cylinder *Renderer::getGraphicsObject(const DataSetId&);
159template Disk *Renderer::getGraphicsObject(const DataSetId&);
160template Group *Renderer::getGraphicsObject(const DataSetId&);
161template Line *Renderer::getGraphicsObject(const DataSetId&);
162template Polygon *Renderer::getGraphicsObject(const DataSetId&);
163template Sphere *Renderer::getGraphicsObject(const DataSetId&);
164
165template <>
166bool Renderer::addGraphicsObject<Box>(const DataSetId& id)
167{
168    Box *gobj;
169    if ((gobj = getGraphicsObject<Box>(id)) != NULL) {
170        WARN("Replacing existing %s %s", gobj->getClassName(), id.c_str());
171        deleteGraphicsObject<Box>(id);
172    }
173
174    gobj = new Box();
175 
176    gobj->setDataSet(NULL, this);
177
178    if (gobj->getProp() == NULL &&
179        gobj->getOverlayProp() == NULL) {
180        delete gobj;
181        return false;
182    } else {
183        if (gobj->getProp())
184            _renderer->AddViewProp(gobj->getProp());
185        if (gobj->getOverlayProp())
186            _renderer->AddViewProp(gobj->getOverlayProp());
187    }
188
189    getGraphicsObjectHashmap<Box>()[id] = gobj;
190
191    initCamera();
192    _needsRedraw = true;
193    return true;
194}
195
196template <>
197bool Renderer::addGraphicsObject<Sphere>(const DataSetId& id)
198{
199    Sphere *gobj;
200    if ((gobj = getGraphicsObject<Sphere>(id)) != NULL) {
201        WARN("Replacing existing %s %s", gobj->getClassName(), id.c_str());
202        deleteGraphicsObject<Sphere>(id);
203    }
204
205    gobj = new Sphere();
206 
207    gobj->setDataSet(NULL, this);
208
209    if (gobj->getProp() == NULL &&
210        gobj->getOverlayProp() == NULL) {
211        delete gobj;
212        return false;
213    } else {
214        if (gobj->getProp())
215            _renderer->AddViewProp(gobj->getProp());
216        if (gobj->getOverlayProp())
217            _renderer->AddViewProp(gobj->getOverlayProp());
218    }
219
220    getGraphicsObjectHashmap<Sphere>()[id] = gobj;
221
222    initCamera();
223    _needsRedraw = true;
224    return true;
225}
226
227/**
228 * \brief Set the volume slice used for mapping volumetric data
229 */
230template <>
231void Renderer::setGraphicsObjectVolumeSlice<HeightMap>(const DataSetId& id, Axis axis, double ratio)
232{
233    HeightMapHashmap::iterator itr;
234
235    bool doAll = false;
236
237    if (id.compare("all") == 0) {
238        itr = _heightMaps.begin();
239        doAll = true;
240    } else {
241        itr = _heightMaps.find(id);
242    }
243
244    if (itr == _heightMaps.end()) {
245        ERROR("HeightMap not found: %s", id.c_str());
246        return;
247    }
248
249    bool initCam = false;
250    do {
251        itr->second->selectVolumeSlice(axis, ratio);
252        if (itr->second->getHeightScale() > 0.0)
253            initCam = true;
254     } while (doAll && ++itr != _heightMaps.end());
255
256    if (initCam)
257        initCamera();
258    else
259        _renderer->ResetCameraClippingRange();
260    _needsRedraw = true;
261}
262
263}
264}
265
266using namespace Rappture::VtkVis;
267
268/**
269 * \brief Create a new Arc and associate it with an ID
270 */
271bool Renderer::addArc(const DataSetId& id, double pt1[3], double pt2[3])
272{
273    Arc *gobj;
274    if ((gobj = getGraphicsObject<Arc>(id)) != NULL) {
275        WARN("Replacing existing %s %s", gobj->getClassName(), id.c_str());
276        deleteGraphicsObject<Arc>(id);
277    }
278
279    gobj = new Arc();
280 
281    gobj->setDataSet(NULL, this);
282
283    if (gobj->getProp() == NULL &&
284        gobj->getOverlayProp() == NULL) {
285        delete gobj;
286        return false;
287    } else {
288        if (gobj->getProp())
289            _renderer->AddViewProp(gobj->getProp());
290        if (gobj->getOverlayProp())
291            _renderer->AddViewProp(gobj->getOverlayProp());
292    }
293
294    gobj->setEndPoints(pt1, pt2);
295
296    getGraphicsObjectHashmap<Arc>()[id] = gobj;
297
298    initCamera();
299    _needsRedraw = true;
300    return true;
301}
302
303/**
304 * \brief Set Arc resolution
305 */
306void Renderer::setArcResolution(const DataSetId& id, int res)
307{
308    ArcHashmap::iterator itr;
309
310    bool doAll = false;
311
312    if (id.compare("all") == 0) {
313        itr = _arcs.begin();
314        doAll = true;
315    } else {
316        itr = _arcs.find(id);
317    }
318    if (itr == _arcs.end()) {
319        ERROR("Arc not found: %s", id.c_str());
320        return;
321    }
322
323    do {
324        itr->second->setResolution(res);
325    } while (doAll && ++itr != _arcs.end());
326
327    _needsRedraw = true;
328}
329
330/**
331 * \brief Create a new Arrow and associate it with an ID
332 */
333bool Renderer::addArrow(const DataSetId& id, double tipRadius, double shaftRadius, double tipLength)
334{
335    Arrow *gobj;
336    if ((gobj = getGraphicsObject<Arrow>(id)) != NULL) {
337        WARN("Replacing existing %s %s", gobj->getClassName(), id.c_str());
338        deleteGraphicsObject<Arrow>(id);
339    }
340
341    gobj = new Arrow();
342 
343    gobj->setDataSet(NULL, this);
344
345    if (gobj->getProp() == NULL &&
346        gobj->getOverlayProp() == NULL) {
347        delete gobj;
348        return false;
349    } else {
350        if (gobj->getProp())
351            _renderer->AddViewProp(gobj->getProp());
352        if (gobj->getOverlayProp())
353            _renderer->AddViewProp(gobj->getOverlayProp());
354    }
355
356    gobj->setRadii(tipRadius, shaftRadius);
357    gobj->setTipLength(tipLength);
358
359    getGraphicsObjectHashmap<Arrow>()[id] = gobj;
360
361    initCamera();
362    _needsRedraw = true;
363    return true;
364}
365
366/**
367 * \brief Set Arrow resolution
368 */
369void Renderer::setArrowResolution(const DataSetId& id, int tipRes, int shaftRes)
370{
371    ArrowHashmap::iterator itr;
372
373    bool doAll = false;
374
375    if (id.compare("all") == 0) {
376        itr = _arrows.begin();
377        doAll = true;
378    } else {
379        itr = _arrows.find(id);
380    }
381    if (itr == _arrows.end()) {
382        ERROR("Arrow not found: %s", id.c_str());
383        return;
384    }
385
386    do {
387        itr->second->setResolution(tipRes, shaftRes);
388    } while (doAll && ++itr != _arrows.end());
389
390    _needsRedraw = true;
391}
392
393/**
394 * \brief Create a new Cone and associate it with an ID
395 */
396bool Renderer::addCone(const DataSetId& id, double radius, double height, bool cap)
397{
398    Cone *gobj;
399    if ((gobj = getGraphicsObject<Cone>(id)) != NULL) {
400        WARN("Replacing existing %s %s", gobj->getClassName(), id.c_str());
401        deleteGraphicsObject<Cone>(id);
402    }
403
404    gobj = new Cone();
405 
406    gobj->setDataSet(NULL, this);
407
408    if (gobj->getProp() == NULL &&
409        gobj->getOverlayProp() == NULL) {
410        delete gobj;
411        return false;
412    } else {
413        if (gobj->getProp())
414            _renderer->AddViewProp(gobj->getProp());
415        if (gobj->getOverlayProp())
416            _renderer->AddViewProp(gobj->getOverlayProp());
417    }
418
419    gobj->setRadius(radius);
420    gobj->setHeight(height);
421    gobj->setCapping(cap);
422
423    getGraphicsObjectHashmap<Cone>()[id] = gobj;
424
425    initCamera();
426    _needsRedraw = true;
427    return true;
428}
429
430/**
431 * \brief Set Cone resolution
432 */
433void Renderer::setConeResolution(const DataSetId& id, int res)
434{
435    ConeHashmap::iterator itr;
436
437    bool doAll = false;
438
439    if (id.compare("all") == 0) {
440        itr = _cones.begin();
441        doAll = true;
442    } else {
443        itr = _cones.find(id);
444    }
445    if (itr == _cones.end()) {
446        ERROR("Cone not found: %s", id.c_str());
447        return;
448    }
449
450    do {
451        itr->second->setResolution(res);
452    } while (doAll && ++itr != _cones.end());
453
454    _needsRedraw = true;
455}
456
457/**
458 * \brief Create a new Contour2D and associate it with the named DataSet
459 */
460bool Renderer::addContour2D(const DataSetId& id, int numContours)
461{
462    DataSetHashmap::iterator itr;
463
464    bool doAll = false;
465
466    if (id.compare("all") == 0) {
467        itr = _dataSets.begin();
468    } else {
469        itr = _dataSets.find(id);
470    }
471    if (itr == _dataSets.end()) {
472        ERROR("Unknown dataset %s", id.c_str());
473        return false;
474    }
475
476    do {
477        DataSet *ds = itr->second;
478        const DataSetId& dsID = ds->getName();
479
480        if (getGraphicsObject<Contour2D>(dsID)) {
481            WARN("Replacing existing Contour2D %s", dsID.c_str());
482            deleteGraphicsObject<Contour2D>(dsID);
483        }
484
485        Contour2D *contour = new Contour2D(numContours);
486 
487        contour->setDataSet(ds, this);
488
489        if (contour->getProp() == NULL) {
490            delete contour;
491            return false;
492        } else {
493            _renderer->AddViewProp(contour->getProp());
494        }
495
496        _contour2Ds[dsID] = contour;
497    } while (doAll && ++itr != _dataSets.end());
498
499    initCamera();
500    _needsRedraw = true;
501    return true;
502}
503
504/**
505 * \brief Create a new Contour2D and associate it with the named DataSet
506 */
507bool Renderer::addContour2D(const DataSetId& id, const std::vector<double>& contours)
508{
509    DataSetHashmap::iterator itr;
510
511    bool doAll = false;
512
513    if (id.compare("all") == 0) {
514        itr = _dataSets.begin();
515    } else {
516        itr = _dataSets.find(id);
517    }
518    if (itr == _dataSets.end()) {
519        ERROR("Unknown dataset %s", id.c_str());
520        return false;
521    }
522
523    do {
524        DataSet *ds = itr->second;
525        const DataSetId& dsID = ds->getName();
526
527        if (getGraphicsObject<Contour2D>(dsID)) {
528            WARN("Replacing existing Contour2D %s", dsID.c_str());
529            deleteGraphicsObject<Contour2D>(dsID);
530        }
531
532        Contour2D *contour = new Contour2D(contours);
533
534        contour->setDataSet(ds, this);
535
536        if (contour->getProp() == NULL) {
537            delete contour;
538            return false;
539        } else {
540            _renderer->AddViewProp(contour->getProp());
541        }
542
543        _contour2Ds[dsID] = contour;
544    } while (doAll && ++itr != _dataSets.end());
545
546    initCamera();
547    _needsRedraw = true;
548    return true;
549}
550
551/**
552 * \brief Set the number of equally spaced contour isolines for the given DataSet
553 */
554void Renderer::setContour2DContours(const DataSetId& id, int numContours)
555{
556    Contour2DHashmap::iterator itr;
557
558    bool doAll = false;
559
560    if (id.compare("all") == 0) {
561        itr = _contour2Ds.begin();
562        doAll = true;
563    } else {
564        itr = _contour2Ds.find(id);
565    }
566    if (itr == _contour2Ds.end()) {
567        ERROR("Contour2D not found: %s", id.c_str());
568        return;
569    }
570
571    do {
572        itr->second->setContours(numContours);
573    } while (doAll && ++itr != _contour2Ds.end());
574
575    _needsRedraw = true;
576}
577
578/**
579 * \brief Set a list of isovalues for the given DataSet
580 */
581void Renderer::setContour2DContourList(const DataSetId& id, const std::vector<double>& contours)
582{
583    Contour2DHashmap::iterator itr;
584
585    bool doAll = false;
586
587    if (id.compare("all") == 0) {
588        itr = _contour2Ds.begin();
589        doAll = true;
590    } else {
591        itr = _contour2Ds.find(id);
592    }
593    if (itr == _contour2Ds.end()) {
594        ERROR("Contour2D not found: %s", id.c_str());
595        return;
596    }
597
598    do {
599        itr->second->setContourList(contours);
600    } while (doAll && ++itr != _contour2Ds.end());
601
602     _needsRedraw = true;
603}
604
605
606/**
607 * \brief Set the color mode for the specified DataSet
608 */
609void Renderer::setContour2DColorMode(const DataSetId& id,
610                                     Contour2D::ColorMode mode,
611                                     DataSet::DataAttributeType type,
612                                     const char *name, double range[2])
613{
614    Contour2DHashmap::iterator itr;
615
616    bool doAll = false;
617
618    if (id.compare("all") == 0) {
619        itr = _contour2Ds.begin();
620        doAll = true;
621    } else {
622        itr = _contour2Ds.find(id);
623    }
624    if (itr == _contour2Ds.end()) {
625        ERROR("Contour2D not found: %s", id.c_str());
626        return;
627    }
628
629    do {
630        itr->second->setColorMode(mode, type, name, range);
631    } while (doAll && ++itr != _contour2Ds.end());
632
633    _needsRedraw = true;
634}
635
636/**
637 * \brief Set the color mode for the specified DataSet
638 */
639void Renderer::setContour2DColorMode(const DataSetId& id,
640                                     Contour2D::ColorMode mode,
641                                     const char *name, double range[2])
642{
643    Contour2DHashmap::iterator itr;
644
645    bool doAll = false;
646
647    if (id.compare("all") == 0) {
648        itr = _contour2Ds.begin();
649        doAll = true;
650    } else {
651        itr = _contour2Ds.find(id);
652    }
653    if (itr == _contour2Ds.end()) {
654        ERROR("Contour2D not found: %s", id.c_str());
655        return;
656    }
657
658    do {
659        itr->second->setColorMode(mode, name, range);
660    } while (doAll && ++itr != _contour2Ds.end());
661
662    _needsRedraw = true;
663}
664
665/**
666 * \brief Create a new Contour3D and associate it with the named DataSet
667 */
668bool Renderer::addContour3D(const DataSetId& id, int numContours)
669{
670    DataSetHashmap::iterator itr;
671
672    bool doAll = false;
673
674    if (id.compare("all") == 0) {
675        itr = _dataSets.begin();
676    } else {
677        itr = _dataSets.find(id);
678    }
679    if (itr == _dataSets.end()) {
680        ERROR("Unknown dataset %s", id.c_str());
681        return false;
682    }
683
684    do {
685        DataSet *ds = itr->second;
686        const DataSetId& dsID = ds->getName();
687
688        if (getGraphicsObject<Contour3D>(dsID)) {
689            WARN("Replacing existing Contour3D %s", dsID.c_str());
690            deleteGraphicsObject<Contour3D>(dsID);
691        }
692
693        Contour3D *contour = new Contour3D(numContours);
694
695        contour->setDataSet(ds, this);
696
697        if (contour->getProp() == NULL) {
698            delete contour;
699            return false;
700        } else {
701            _renderer->AddViewProp(contour->getProp());
702        }
703
704        _contour3Ds[dsID] = contour;
705    } while (doAll && ++itr != _dataSets.end());
706
707    if (_cameraMode == IMAGE)
708        setCameraMode(PERSPECTIVE);
709    initCamera();
710    _needsRedraw = true;
711    return true;
712}
713
714/**
715 * \brief Create a new Contour3D and associate it with the named DataSet
716 */
717bool Renderer::addContour3D(const DataSetId& id,const std::vector<double>& contours)
718{
719    DataSetHashmap::iterator itr;
720
721    bool doAll = false;
722
723    if (id.compare("all") == 0) {
724        itr = _dataSets.begin();
725    } else {
726        itr = _dataSets.find(id);
727    }
728    if (itr == _dataSets.end()) {
729        ERROR("Unknown dataset %s", id.c_str());
730        return false;
731    }
732
733    do {
734        DataSet *ds = itr->second;
735        const DataSetId& dsID = ds->getName();
736
737        if (getGraphicsObject<Contour3D>(dsID)) {
738            WARN("Replacing existing Contour3D %s", dsID.c_str());
739            deleteGraphicsObject<Contour3D>(dsID);
740        }
741
742        Contour3D *contour = new Contour3D(contours);
743
744        contour->setDataSet(ds, this);
745
746        if (contour->getProp() == NULL) {
747            delete contour;
748            return false;
749        } else {
750            _renderer->AddViewProp(contour->getProp());
751        }
752
753        _contour3Ds[dsID] = contour;
754    } while (doAll && ++itr != _dataSets.end());
755
756    initCamera();
757    _needsRedraw = true;
758    return true;
759}
760
761/**
762 * \brief Set the number of equally spaced isosurfaces for the given DataSet
763 */
764void Renderer::setContour3DContours(const DataSetId& id, int numContours)
765{
766    Contour3DHashmap::iterator itr;
767
768    bool doAll = false;
769
770    if (id.compare("all") == 0) {
771        itr = _contour3Ds.begin();
772        doAll = true;
773    } else {
774        itr = _contour3Ds.find(id);
775    }
776    if (itr == _contour3Ds.end()) {
777        ERROR("Contour3D not found: %s", id.c_str());
778        return;
779    }
780
781    do {
782        itr->second->setContours(numContours);
783     } while (doAll && ++itr != _contour3Ds.end());
784
785    initCamera();
786    _needsRedraw = true;
787}
788
789/**
790 * \brief Set a list of isovalues for the given DataSet
791 */
792void Renderer::setContour3DContourList(const DataSetId& id, const std::vector<double>& contours)
793{
794    Contour3DHashmap::iterator itr;
795
796    bool doAll = false;
797
798    if (id.compare("all") == 0) {
799        itr = _contour3Ds.begin();
800        doAll = true;
801    } else {
802        itr = _contour3Ds.find(id);
803    }
804    if (itr == _contour3Ds.end()) {
805        ERROR("Contour3D not found: %s", id.c_str());
806        return;
807    }
808
809    do {
810        itr->second->setContourList(contours);
811    } while (doAll && ++itr != _contour3Ds.end());
812
813    initCamera();
814     _needsRedraw = true;
815}
816
817/**
818 * \brief Set the visibility of cutplane outlines
819 */
820void Renderer::setCutplaneOutlineVisibility(const DataSetId& id, bool state)
821{
822    CutplaneHashmap::iterator itr;
823
824    bool doAll = false;
825
826    if (id.compare("all") == 0) {
827        itr = _cutplanes.begin();
828        doAll = true;
829    } else {
830        itr = _cutplanes.find(id);
831    }
832
833    if (itr == _cutplanes.end()) {
834        ERROR("Cutplane not found: %s", id.c_str());
835        return;
836    }
837
838    do {
839        itr->second->setOutlineVisibility(state);
840     } while (doAll && ++itr != _cutplanes.end());
841
842    _renderer->ResetCameraClippingRange();
843    _needsRedraw = true;
844}
845
846/**
847 * \brief Set the visibility of slices in one of the three axes
848 */
849void Renderer::setCutplaneSliceVisibility(const DataSetId& id, Axis axis, bool state)
850{
851    CutplaneHashmap::iterator itr;
852
853    bool doAll = false;
854
855    if (id.compare("all") == 0) {
856        itr = _cutplanes.begin();
857        doAll = true;
858    } else {
859        itr = _cutplanes.find(id);
860    }
861
862    if (itr == _cutplanes.end()) {
863        ERROR("Cutplane not found: %s", id.c_str());
864        return;
865    }
866
867    do {
868        itr->second->setSliceVisibility(axis, state);
869     } while (doAll && ++itr != _cutplanes.end());
870
871    _renderer->ResetCameraClippingRange();
872    _needsRedraw = true;
873}
874
875/**
876 * \brief Set the color mode for the specified DataSet
877 */
878void Renderer::setCutplaneColorMode(const DataSetId& id,
879                                    Cutplane::ColorMode mode,
880                                    DataSet::DataAttributeType type,
881                                    const char *name, double range[2])
882{
883    CutplaneHashmap::iterator itr;
884
885    bool doAll = false;
886
887    if (id.compare("all") == 0) {
888        itr = _cutplanes.begin();
889        doAll = true;
890    } else {
891        itr = _cutplanes.find(id);
892    }
893    if (itr == _cutplanes.end()) {
894        ERROR("Cutplane not found: %s", id.c_str());
895        return;
896    }
897
898    do {
899        itr->second->setColorMode(mode, type, name, range);
900    } while (doAll && ++itr != _cutplanes.end());
901
902    _needsRedraw = true;
903}
904
905/**
906 * \brief Set the color mode for the specified DataSet
907 */
908void Renderer::setCutplaneColorMode(const DataSetId& id,
909                                    Cutplane::ColorMode mode,
910                                    const char *name, double range[2])
911{
912    CutplaneHashmap::iterator itr;
913
914    bool doAll = false;
915
916    if (id.compare("all") == 0) {
917        itr = _cutplanes.begin();
918        doAll = true;
919    } else {
920        itr = _cutplanes.find(id);
921    }
922    if (itr == _cutplanes.end()) {
923        ERROR("Cutplane not found: %s", id.c_str());
924        return;
925    }
926
927    do {
928        itr->second->setColorMode(mode, name, range);
929    } while (doAll && ++itr != _cutplanes.end());
930
931    _needsRedraw = true;
932}
933
934/**
935 * \brief Create a new Cylinder and associate it with an ID
936 */
937bool Renderer::addCylinder(const DataSetId& id, double radius, double height, bool cap)
938{
939    Cylinder *gobj;
940    if ((gobj = getGraphicsObject<Cylinder>(id)) != NULL) {
941        WARN("Replacing existing %s %s", gobj->getClassName(), id.c_str());
942        deleteGraphicsObject<Cylinder>(id);
943    }
944
945    gobj = new Cylinder();
946 
947    gobj->setDataSet(NULL, this);
948
949    if (gobj->getProp() == NULL &&
950        gobj->getOverlayProp() == NULL) {
951        delete gobj;
952        return false;
953    } else {
954        if (gobj->getProp())
955            _renderer->AddViewProp(gobj->getProp());
956        if (gobj->getOverlayProp())
957            _renderer->AddViewProp(gobj->getOverlayProp());
958    }
959
960    gobj->setRadius(radius);
961    gobj->setHeight(height);
962    gobj->setCapping(cap);
963
964    getGraphicsObjectHashmap<Cylinder>()[id] = gobj;
965
966    initCamera();
967    _needsRedraw = true;
968    return true;
969}
970
971/**
972 * \brief Set Cylinder resolution
973 */
974void Renderer::setCylinderResolution(const DataSetId& id, int res)
975{
976    CylinderHashmap::iterator itr;
977
978    bool doAll = false;
979
980    if (id.compare("all") == 0) {
981        itr = _cylinders.begin();
982        doAll = true;
983    } else {
984        itr = _cylinders.find(id);
985    }
986    if (itr == _cylinders.end()) {
987        ERROR("Cylinder not found: %s", id.c_str());
988        return;
989    }
990
991    do {
992        itr->second->setResolution(res);
993    } while (doAll && ++itr != _cylinders.end());
994
995    _needsRedraw = true;
996}
997
998/**
999 * \brief Create a new Disk and associate it with an ID
1000 */
1001bool Renderer::addDisk(const DataSetId& id, double innerRadius, double outerRadius)
1002{
1003    Disk *gobj;
1004    if ((gobj = getGraphicsObject<Disk>(id)) != NULL) {
1005        WARN("Replacing existing %s %s", gobj->getClassName(), id.c_str());
1006        deleteGraphicsObject<Disk>(id);
1007    }
1008
1009    gobj = new Disk();
1010 
1011    gobj->setDataSet(NULL, this);
1012
1013    if (gobj->getProp() == NULL &&
1014        gobj->getOverlayProp() == NULL) {
1015        delete gobj;
1016        return false;
1017    } else {
1018        if (gobj->getProp())
1019            _renderer->AddViewProp(gobj->getProp());
1020        if (gobj->getOverlayProp())
1021            _renderer->AddViewProp(gobj->getOverlayProp());
1022    }
1023
1024    gobj->setRadii(innerRadius, outerRadius);
1025
1026    getGraphicsObjectHashmap<Disk>()[id] = gobj;
1027
1028    initCamera();
1029    _needsRedraw = true;
1030    return true;
1031}
1032
1033/**
1034 * \brief Set Disk resolution
1035 */
1036void Renderer::setDiskResolution(const DataSetId& id, int resRadial, int resCircum)
1037{
1038    DiskHashmap::iterator itr;
1039
1040    bool doAll = false;
1041
1042    if (id.compare("all") == 0) {
1043        itr = _disks.begin();
1044        doAll = true;
1045    } else {
1046        itr = _disks.find(id);
1047    }
1048    if (itr == _disks.end()) {
1049        ERROR("Disk not found: %s", id.c_str());
1050        return;
1051    }
1052
1053    do {
1054        itr->second->setResolution(resRadial, resCircum);
1055    } while (doAll && ++itr != _disks.end());
1056
1057    _needsRedraw = true;
1058}
1059
1060/**
1061 * \brief Create a new Glyphs and associate it with the named DataSet
1062 */
1063bool Renderer::addGlyphs(const DataSetId& id, Glyphs::GlyphShape shape)
1064{
1065    DataSetHashmap::iterator itr;
1066
1067    bool doAll = false;
1068
1069    if (id.compare("all") == 0) {
1070        itr = _dataSets.begin();
1071    } else {
1072        itr = _dataSets.find(id);
1073    }
1074    if (itr == _dataSets.end()) {
1075        ERROR("Unknown dataset %s", id.c_str());
1076        return false;
1077    }
1078
1079    do {
1080        DataSet *ds = itr->second;
1081        const DataSetId& dsID = ds->getName();
1082
1083        if (getGraphicsObject<Glyphs>(dsID)) {
1084            WARN("Replacing existing Glyphs %s", dsID.c_str());
1085            deleteGraphicsObject<Glyphs>(dsID);
1086        }
1087
1088        Glyphs *glyphs = new Glyphs(shape);
1089
1090        glyphs->setDataSet(ds, this);
1091
1092        if (glyphs->getProp() == NULL) {
1093            delete glyphs;
1094            return false;
1095        } else {
1096            _renderer->AddViewProp(glyphs->getProp());
1097        }
1098
1099        _glyphs[dsID] = glyphs;
1100    } while (doAll && ++itr != _dataSets.end());
1101
1102    initCamera();
1103
1104    _needsRedraw = true;
1105    return true;
1106}
1107
1108/**
1109 * \brief Set the color mode for the specified DataSet
1110 */
1111void Renderer::setGlyphsColorMode(const DataSetId& id,
1112                                  Glyphs::ColorMode mode,
1113                                  const char *name, double range[2])
1114{
1115    GlyphsHashmap::iterator itr;
1116
1117    bool doAll = false;
1118
1119    if (id.compare("all") == 0) {
1120        itr = _glyphs.begin();
1121        doAll = true;
1122    } else {
1123        itr = _glyphs.find(id);
1124    }
1125    if (itr == _glyphs.end()) {
1126        ERROR("Glyphs not found: %s", id.c_str());
1127        return;
1128    }
1129
1130    do {
1131#ifdef HAVE_GLYPH3D_MAPPER
1132        itr->second->setColorMode(mode, name, range);
1133#else
1134        if (name != NULL && strlen(name) > 0) {
1135            WARN("Glyphs color mode doesn't support named fields for VTK < 5.8.0");
1136        }
1137        itr->second->setColorMode(mode);
1138#endif
1139    } while (doAll && ++itr != _glyphs.end());
1140
1141    _needsRedraw = true;
1142}
1143
1144/**
1145 * \brief Controls the array used to scale glyphs for the given DataSet
1146 */
1147void Renderer::setGlyphsScalingMode(const DataSetId& id,
1148                                    Glyphs::ScalingMode mode,
1149                                    const char *name, double range[2])
1150{
1151    GlyphsHashmap::iterator itr;
1152
1153    bool doAll = false;
1154
1155    if (id.compare("all") == 0) {
1156        itr = _glyphs.begin();
1157        doAll = true;
1158    } else {
1159        itr = _glyphs.find(id);
1160    }
1161    if (itr == _glyphs.end()) {
1162        ERROR("Glyphs not found: %s", id.c_str());
1163        return;
1164    }
1165
1166    do {
1167#ifdef HAVE_GLYPH3D_MAPPER
1168        itr->second->setScalingMode(mode, name, range);
1169#else
1170        if (name != NULL && strlen(name) > 0) {
1171            WARN("Glyphs scaling mode doesn't support named fields for VTK < 5.8.0");
1172        }
1173        itr->second->setScalingMode(mode);
1174#endif
1175    } while (doAll && ++itr != _glyphs.end());
1176
1177    _renderer->ResetCameraClippingRange();
1178    _needsRedraw = true;
1179}
1180
1181/**
1182 * \brief Controls if field data range is normalized to [0,1] before
1183 * applying scale factor for the given DataSet
1184 */
1185void Renderer::setGlyphsNormalizeScale(const DataSetId& id, bool normalize)
1186{
1187    GlyphsHashmap::iterator itr;
1188
1189    bool doAll = false;
1190
1191    if (id.compare("all") == 0) {
1192        itr = _glyphs.begin();
1193        doAll = true;
1194    } else {
1195        itr = _glyphs.find(id);
1196    }
1197    if (itr == _glyphs.end()) {
1198        ERROR("Glyphs not found: %s", id.c_str());
1199        return;
1200    }
1201
1202    do {
1203        itr->second->setNormalizeScale(normalize);
1204    } while (doAll && ++itr != _glyphs.end());
1205
1206    _renderer->ResetCameraClippingRange();
1207    _needsRedraw = true;
1208}
1209
1210/**
1211 * \brief Controls if glyphs are oriented from a vector field for the
1212 * given DataSet
1213 */
1214void Renderer::setGlyphsOrientMode(const DataSetId& id, bool state,
1215                                   const char *name)
1216{
1217    GlyphsHashmap::iterator itr;
1218
1219    bool doAll = false;
1220
1221    if (id.compare("all") == 0) {
1222        itr = _glyphs.begin();
1223        doAll = true;
1224    } else {
1225        itr = _glyphs.find(id);
1226    }
1227    if (itr == _glyphs.end()) {
1228        ERROR("Glyphs not found: %s", id.c_str());
1229        return;
1230    }
1231
1232    do {
1233#ifdef HAVE_GLYPH3D_MAPPER
1234        itr->second->setOrientMode(state, name);
1235#else
1236        if (name != NULL && strlen(name) > 0) {
1237            WARN("Glyphs orient mode doesn't support named fields for VTK < 5.8.0");
1238        }
1239        itr->second->setOrient(state);
1240#endif
1241    } while (doAll && ++itr != _glyphs.end());
1242
1243    _renderer->ResetCameraClippingRange();
1244    _needsRedraw = true;
1245}
1246
1247/**
1248 * \brief Set the shape of Glyphs for the given DataSet
1249 */
1250void Renderer::setGlyphsShape(const DataSetId& id, Glyphs::GlyphShape shape)
1251{
1252    GlyphsHashmap::iterator itr;
1253
1254    bool doAll = false;
1255
1256    if (id.compare("all") == 0) {
1257        itr = _glyphs.begin();
1258        doAll = true;
1259    } else {
1260        itr = _glyphs.find(id);
1261    }
1262    if (itr == _glyphs.end()) {
1263        ERROR("Glyphs not found: %s", id.c_str());
1264        return;
1265    }
1266
1267    do {
1268        itr->second->setGlyphShape(shape);
1269    } while (doAll && ++itr != _glyphs.end());
1270
1271    _renderer->ResetCameraClippingRange();
1272    _needsRedraw = true;
1273}
1274
1275/**
1276 * \brief Set the glyph scaling factor for the given DataSet
1277 */
1278void Renderer::setGlyphsScaleFactor(const DataSetId& id, double scale)
1279{
1280    GlyphsHashmap::iterator itr;
1281
1282    bool doAll = false;
1283
1284    if (id.compare("all") == 0) {
1285        itr = _glyphs.begin();
1286        doAll = true;
1287    } else {
1288        itr = _glyphs.find(id);
1289    }
1290    if (itr == _glyphs.end()) {
1291        ERROR("Glyphs not found: %s", id.c_str());
1292        return;
1293    }
1294
1295    do {
1296        itr->second->setScaleFactor(scale);
1297    } while (doAll && ++itr != _glyphs.end());
1298
1299    initCamera();
1300    _needsRedraw = true;
1301}
1302
1303/**
1304 * \brief Create a new HeightMap and associate it with the named DataSet
1305 */
1306bool Renderer::addHeightMap(const DataSetId& id, int numContours, double heightScale)
1307{
1308    DataSetHashmap::iterator itr;
1309
1310    bool doAll = false;
1311
1312    if (id.compare("all") == 0) {
1313        itr = _dataSets.begin();
1314    } else {
1315        itr = _dataSets.find(id);
1316    }
1317    if (itr == _dataSets.end()) {
1318        ERROR("Unknown dataset %s", id.c_str());
1319        return false;
1320    }
1321
1322    do {
1323        DataSet *ds = itr->second;
1324        const DataSetId& dsID = ds->getName();
1325
1326        if (getGraphicsObject<HeightMap>(dsID)) {
1327            WARN("Replacing existing HeightMap %s", dsID.c_str());
1328            deleteGraphicsObject<HeightMap>(dsID);
1329        }
1330
1331        HeightMap *hmap = new HeightMap(numContours, heightScale);
1332
1333        hmap->setDataSet(ds, this);
1334
1335        if (hmap->getProp() == NULL) {
1336            delete hmap;
1337            return false;
1338        } else {
1339            _renderer->AddViewProp(hmap->getProp());
1340        }
1341
1342        _heightMaps[dsID] = hmap;
1343    } while (doAll && ++itr != _dataSets.end());
1344
1345    initCamera();
1346
1347    _needsRedraw = true;
1348    return true;
1349}
1350
1351/**
1352 * \brief Create a new HeightMap and associate it with the named DataSet
1353 */
1354bool Renderer::addHeightMap(const DataSetId& id, const std::vector<double>& contours, double heightScale)
1355{
1356    DataSetHashmap::iterator itr;
1357
1358    bool doAll = false;
1359
1360    if (id.compare("all") == 0) {
1361        itr = _dataSets.begin();
1362    } else {
1363        itr = _dataSets.find(id);
1364    }
1365    if (itr == _dataSets.end()) {
1366        ERROR("Unknown dataset %s", id.c_str());
1367        return false;
1368    }
1369
1370    do {
1371        DataSet *ds = itr->second;
1372        const DataSetId& dsID = ds->getName();
1373
1374        if (getGraphicsObject<HeightMap>(dsID)) {
1375            WARN("Replacing existing HeightMap %s", dsID.c_str());
1376            deleteGraphicsObject<HeightMap>(dsID);
1377        }
1378
1379        HeightMap *hmap = new HeightMap(contours, heightScale);
1380
1381        hmap->setDataSet(ds, this);
1382
1383        if (hmap->getProp() == NULL) {
1384            delete hmap;
1385            return false;
1386        } else {
1387            _renderer->AddViewProp(hmap->getProp());
1388        }
1389
1390        _heightMaps[dsID] = hmap;
1391    } while (doAll && ++itr != _dataSets.end());
1392
1393    initCamera();
1394
1395    _needsRedraw = true;
1396    return true;
1397}
1398
1399/**
1400 * \brief Set amount to scale scalar values when creating elevations
1401 * in the height map
1402 */
1403void Renderer::setHeightMapHeightScale(const DataSetId& id, double scale)
1404{
1405    HeightMapHashmap::iterator itr;
1406
1407    bool doAll = false;
1408
1409    if (id.compare("all") == 0) {
1410        itr = _heightMaps.begin();
1411        doAll = true;
1412    } else {
1413        itr = _heightMaps.find(id);
1414    }
1415
1416    if (itr == _heightMaps.end()) {
1417        ERROR("HeightMap not found: %s", id.c_str());
1418        return;
1419    }
1420
1421    do {
1422        itr->second->setHeightScale(scale);
1423     } while (doAll && ++itr != _heightMaps.end());
1424
1425    _renderer->ResetCameraClippingRange();
1426    resetAxes();
1427    _needsRedraw = true;
1428}
1429
1430/**
1431 * \brief Set the number of equally spaced contour isolines for the given DataSet
1432 */
1433void Renderer::setHeightMapNumContours(const DataSetId& id, int numContours)
1434{
1435    HeightMapHashmap::iterator itr;
1436
1437    bool doAll = false;
1438
1439    if (id.compare("all") == 0) {
1440        itr = _heightMaps.begin();
1441        doAll = true;
1442    } else {
1443        itr = _heightMaps.find(id);
1444    }
1445    if (itr == _heightMaps.end()) {
1446        ERROR("HeightMap not found: %s", id.c_str());
1447        return;
1448    }
1449
1450    do {
1451        itr->second->setNumContours(numContours);
1452    } while (doAll && ++itr != _heightMaps.end());
1453
1454    _needsRedraw = true;
1455}
1456
1457/**
1458 * \brief Set a list of height map contour isovalues for the given DataSet
1459 */
1460void Renderer::setHeightMapContourList(const DataSetId& id, const std::vector<double>& contours)
1461{
1462    HeightMapHashmap::iterator itr;
1463
1464    bool doAll = false;
1465
1466    if (id.compare("all") == 0) {
1467        itr = _heightMaps.begin();
1468        doAll = true;
1469    } else {
1470        itr = _heightMaps.find(id);
1471    }
1472    if (itr == _heightMaps.end()) {
1473        ERROR("HeightMap not found: %s", id.c_str());
1474        return;
1475    }
1476
1477    do {
1478        itr->second->setContourList(contours);
1479    } while (doAll && ++itr != _heightMaps.end());
1480
1481     _needsRedraw = true;
1482}
1483
1484/**
1485 * \brief Turn on/off rendering height map contour lines for the given DataSet
1486 */
1487void Renderer::setHeightMapContourLineVisibility(const DataSetId& id, bool state)
1488{
1489    HeightMapHashmap::iterator itr;
1490
1491    bool doAll = false;
1492
1493    if (id.compare("all") == 0) {
1494        itr = _heightMaps.begin();
1495        doAll = true;
1496    } else {
1497        itr = _heightMaps.find(id);
1498    }
1499    if (itr == _heightMaps.end()) {
1500        ERROR("HeightMap not found: %s", id.c_str());
1501        return;
1502    }
1503
1504    do {
1505        itr->second->setContourLineVisibility(state);
1506    } while (doAll && ++itr != _heightMaps.end());
1507
1508    _needsRedraw = true;
1509}
1510
1511/**
1512 * \brief Turn on/off rendering height map colormap surface for the given DataSet
1513 */
1514void Renderer::setHeightMapContourSurfaceVisibility(const DataSetId& id, bool state)
1515{
1516    HeightMapHashmap::iterator itr;
1517
1518    bool doAll = false;
1519
1520    if (id.compare("all") == 0) {
1521        itr = _heightMaps.begin();
1522        doAll = true;
1523    } else {
1524        itr = _heightMaps.find(id);
1525    }
1526    if (itr == _heightMaps.end()) {
1527        ERROR("HeightMap not found: %s", id.c_str());
1528        return;
1529    }
1530
1531    do {
1532        itr->second->setContourSurfaceVisibility(state);
1533    } while (doAll && ++itr != _heightMaps.end());
1534
1535    _needsRedraw = true;
1536}
1537
1538/**
1539 * \brief Set the RGB height map isoline color for the specified DataSet
1540 */
1541void Renderer::setHeightMapContourEdgeColor(const DataSetId& id, float color[3])
1542{
1543    HeightMapHashmap::iterator itr;
1544
1545    bool doAll = false;
1546
1547    if (id.compare("all") == 0) {
1548        itr = _heightMaps.begin();
1549        doAll = true;
1550    } else {
1551        itr = _heightMaps.find(id);
1552    }
1553    if (itr == _heightMaps.end()) {
1554        ERROR("HeightMap not found: %s", id.c_str());
1555        return;
1556    }
1557
1558    do {
1559        itr->second->setContourEdgeColor(color);
1560    } while (doAll && ++itr != _heightMaps.end());
1561
1562    _needsRedraw = true;
1563}
1564
1565/**
1566 * \brief Set the height map isoline width for the specified DataSet (may be a no-op)
1567 *
1568 * If the OpenGL implementation/hardware does not support wide lines,
1569 * this function may not have an effect.
1570 */
1571void Renderer::setHeightMapContourEdgeWidth(const DataSetId& id, float edgeWidth)
1572{
1573    HeightMapHashmap::iterator itr;
1574
1575    bool doAll = false;
1576
1577    if (id.compare("all") == 0) {
1578        itr = _heightMaps.begin();
1579        doAll = true;
1580    } else {
1581        itr = _heightMaps.find(id);
1582    }
1583    if (itr == _heightMaps.end()) {
1584        ERROR("HeightMap not found: %s", id.c_str());
1585        return;
1586    }
1587
1588    do {
1589        itr->second->setContourEdgeWidth(edgeWidth);
1590    } while (doAll && ++itr != _heightMaps.end());
1591
1592    _needsRedraw = true;
1593}
1594
1595/**
1596 * \brief Create a new Line and associate it with an ID
1597 */
1598bool Renderer::addLine(const DataSetId& id, double pt1[3], double pt2[3])
1599{
1600    Line *gobj;
1601    if ((gobj = getGraphicsObject<Line>(id)) != NULL) {
1602        WARN("Replacing existing %s %s", gobj->getClassName(), id.c_str());
1603        deleteGraphicsObject<Line>(id);
1604    }
1605
1606    gobj = new Line();
1607 
1608    gobj->setDataSet(NULL, this);
1609
1610    if (gobj->getProp() == NULL &&
1611        gobj->getOverlayProp() == NULL) {
1612        delete gobj;
1613        return false;
1614    } else {
1615        if (gobj->getProp())
1616            _renderer->AddViewProp(gobj->getProp());
1617        if (gobj->getOverlayProp())
1618            _renderer->AddViewProp(gobj->getOverlayProp());
1619    }
1620
1621    gobj->setEndPoints(pt1, pt2);
1622
1623    getGraphicsObjectHashmap<Line>()[id] = gobj;
1624
1625    initCamera();
1626    _needsRedraw = true;
1627    return true;
1628}
1629
1630/**
1631 * \brief Set radius scale factor for atoms
1632 */
1633void Renderer::setMoleculeAtomRadiusScale(const DataSetId& id, double scale)
1634{
1635    MoleculeHashmap::iterator itr;
1636
1637    bool doAll = false;
1638
1639    if (id.compare("all") == 0) {
1640        itr = _molecules.begin();
1641        doAll = true;
1642    } else {
1643        itr = _molecules.find(id);
1644    }
1645    if (itr == _molecules.end()) {
1646        ERROR("Molecule not found: %s", id.c_str());
1647        return;
1648    }
1649
1650    do {
1651        itr->second->setAtomRadiusScale(scale);
1652    } while (doAll && ++itr != _molecules.end());
1653
1654    _renderer->ResetCameraClippingRange();
1655    resetAxes();
1656    _needsRedraw = true;
1657}
1658
1659/**
1660 * \brief Set radius standard for scaling atoms
1661 */
1662void Renderer::setMoleculeAtomScaling(const DataSetId& id, Molecule::AtomScaling scaling)
1663{
1664    MoleculeHashmap::iterator itr;
1665
1666    bool doAll = false;
1667
1668    if (id.compare("all") == 0) {
1669        itr = _molecules.begin();
1670        doAll = true;
1671    } else {
1672        itr = _molecules.find(id);
1673    }
1674    if (itr == _molecules.end()) {
1675        ERROR("Molecule not found: %s", id.c_str());
1676        return;
1677    }
1678
1679    do {
1680        itr->second->setAtomScaling(scaling);
1681    } while (doAll && ++itr != _molecules.end());
1682
1683    _renderer->ResetCameraClippingRange();
1684    resetAxes();
1685    _needsRedraw = true;
1686}
1687
1688/**
1689 * \brief Turn on/off rendering of the Molecule atoms for the given DataSet
1690 */
1691void Renderer::setMoleculeAtomVisibility(const DataSetId& id, bool state)
1692{
1693    MoleculeHashmap::iterator itr;
1694
1695    bool doAll = false;
1696
1697    if (id.compare("all") == 0) {
1698        itr = _molecules.begin();
1699        doAll = true;
1700    } else {
1701        itr = _molecules.find(id);
1702    }
1703    if (itr == _molecules.end()) {
1704        ERROR("Molecule not found: %s", id.c_str());
1705        return;
1706    }
1707
1708    do {
1709        itr->second->setAtomVisibility(state);
1710    } while (doAll && ++itr != _molecules.end());
1711
1712    _needsRedraw = true;
1713}
1714
1715/**
1716 * \brief Turn on/off rendering of the Molecule atom labels for the given DataSet
1717 */
1718void Renderer::setMoleculeAtomLabelVisibility(const DataSetId& id, bool state)
1719{
1720    MoleculeHashmap::iterator itr;
1721
1722    bool doAll = false;
1723
1724    if (id.compare("all") == 0) {
1725        itr = _molecules.begin();
1726        doAll = true;
1727    } else {
1728        itr = _molecules.find(id);
1729    }
1730    if (itr == _molecules.end()) {
1731        ERROR("Molecule not found: %s", id.c_str());
1732        return;
1733    }
1734
1735    do {
1736        itr->second->setAtomLabelVisibility(state);
1737    } while (doAll && ++itr != _molecules.end());
1738
1739    _needsRedraw = true;
1740}
1741
1742/**
1743 * \brief Set radius scale factor for atoms
1744 */
1745void Renderer::setMoleculeBondRadiusScale(const DataSetId& id, double scale)
1746{
1747    MoleculeHashmap::iterator itr;
1748
1749    bool doAll = false;
1750
1751    if (id.compare("all") == 0) {
1752        itr = _molecules.begin();
1753        doAll = true;
1754    } else {
1755        itr = _molecules.find(id);
1756    }
1757    if (itr == _molecules.end()) {
1758        ERROR("Molecule not found: %s", id.c_str());
1759        return;
1760    }
1761
1762    do {
1763        itr->second->setBondRadiusScale(scale);
1764    } while (doAll && ++itr != _molecules.end());
1765
1766    _renderer->ResetCameraClippingRange();
1767    resetAxes();
1768    _needsRedraw = true;
1769}
1770
1771/**
1772 * \brief Turn on/off rendering of the Molecule bonds for the given DataSet
1773 */
1774void Renderer::setMoleculeBondVisibility(const DataSetId& id, bool state)
1775{
1776    MoleculeHashmap::iterator itr;
1777
1778    bool doAll = false;
1779
1780    if (id.compare("all") == 0) {
1781        itr = _molecules.begin();
1782        doAll = true;
1783    } else {
1784        itr = _molecules.find(id);
1785    }
1786    if (itr == _molecules.end()) {
1787        ERROR("Molecule not found: %s", id.c_str());
1788        return;
1789    }
1790
1791    do {
1792        itr->second->setBondVisibility(state);
1793    } while (doAll && ++itr != _molecules.end());
1794
1795    _needsRedraw = true;
1796}
1797
1798void Renderer::setMoleculeBondStyle(const DataSetId& id, Molecule::BondStyle style)
1799{
1800    MoleculeHashmap::iterator itr;
1801
1802    bool doAll = false;
1803
1804    if (id.compare("all") == 0) {
1805        itr = _molecules.begin();
1806        doAll = true;
1807    } else {
1808        itr = _molecules.find(id);
1809    }
1810    if (itr == _molecules.end()) {
1811        ERROR("Molecule not found: %s", id.c_str());
1812        return;
1813    }
1814
1815    do {
1816        itr->second->setBondStyle(style);
1817    } while (doAll && ++itr != _molecules.end());
1818
1819    _needsRedraw = true;
1820}
1821
1822void Renderer::setMoleculeBondColorMode(const DataSetId& id, Molecule::BondColorMode mode)
1823{
1824    MoleculeHashmap::iterator itr;
1825
1826    bool doAll = false;
1827
1828    if (id.compare("all") == 0) {
1829        itr = _molecules.begin();
1830        doAll = true;
1831    } else {
1832        itr = _molecules.find(id);
1833    }
1834    if (itr == _molecules.end()) {
1835        ERROR("Molecule not found: %s", id.c_str());
1836        return;
1837    }
1838
1839    do {
1840        itr->second->setBondColorMode(mode);
1841    } while (doAll && ++itr != _molecules.end());
1842
1843    _needsRedraw = true;
1844}
1845
1846void Renderer::setMoleculeBondColor(const DataSetId& id, float color[3])
1847{
1848    MoleculeHashmap::iterator itr;
1849
1850    bool doAll = false;
1851
1852    if (id.compare("all") == 0) {
1853        itr = _molecules.begin();
1854        doAll = true;
1855    } else {
1856        itr = _molecules.find(id);
1857    }
1858    if (itr == _molecules.end()) {
1859        ERROR("Molecule not found: %s", id.c_str());
1860        return;
1861    }
1862
1863    do {
1864        itr->second->setBondColor(color);
1865    } while (doAll && ++itr != _molecules.end());
1866
1867    _needsRedraw = true;
1868}
1869
1870
1871/**
1872 * \brief Set the color mode for the specified DataSet
1873 */
1874void Renderer::setMoleculeColorMode(const DataSetId& id,
1875                                    Molecule::ColorMode mode,
1876                                    DataSet::DataAttributeType type,
1877                                    const char *name, double range[2])
1878{
1879    MoleculeHashmap::iterator itr;
1880
1881    bool doAll = false;
1882
1883    if (id.compare("all") == 0) {
1884        itr = _molecules.begin();
1885        doAll = true;
1886    } else {
1887        itr = _molecules.find(id);
1888    }
1889    if (itr == _molecules.end()) {
1890        ERROR("Molecule not found: %s", id.c_str());
1891        return;
1892    }
1893
1894    do {
1895        itr->second->setColorMode(mode, type, name, range);
1896    } while (doAll && ++itr != _molecules.end());
1897
1898    _needsRedraw = true;
1899}
1900
1901/**
1902 * \brief Set the color mode for the specified DataSet
1903 */
1904void Renderer::setMoleculeColorMode(const DataSetId& id,
1905                                    Molecule::ColorMode mode,
1906                                    const char *name, double range[2])
1907{
1908    MoleculeHashmap::iterator itr;
1909
1910    bool doAll = false;
1911
1912    if (id.compare("all") == 0) {
1913        itr = _molecules.begin();
1914        doAll = true;
1915    } else {
1916        itr = _molecules.find(id);
1917    }
1918    if (itr == _molecules.end()) {
1919        ERROR("Molecule not found: %s", id.c_str());
1920        return;
1921    }
1922
1923    do {
1924        itr->second->setColorMode(mode, name, range);
1925    } while (doAll && ++itr != _molecules.end());
1926
1927    _needsRedraw = true;
1928}
1929
1930/**
1931 * \brief Create a new n-sided regular Polygon and associate it with an ID
1932 */
1933bool Renderer::addPolygon(const DataSetId& id, int numSides)
1934{
1935    Polygon *gobj;
1936    if ((gobj = getGraphicsObject<Polygon>(id)) != NULL) {
1937        WARN("Replacing existing %s %s", gobj->getClassName(), id.c_str());
1938        deleteGraphicsObject<Polygon>(id);
1939    }
1940
1941    gobj = new Polygon();
1942 
1943    gobj->setDataSet(NULL, this);
1944
1945    if (gobj->getProp() == NULL &&
1946        gobj->getOverlayProp() == NULL) {
1947        delete gobj;
1948        return false;
1949    } else {
1950        if (gobj->getProp())
1951            _renderer->AddViewProp(gobj->getProp());
1952        if (gobj->getOverlayProp())
1953            _renderer->AddViewProp(gobj->getOverlayProp());
1954    }
1955
1956    gobj->setNumberOfSides(numSides);
1957
1958    getGraphicsObjectHashmap<Polygon>()[id] = gobj;
1959
1960    initCamera();
1961    _needsRedraw = true;
1962    return true;
1963}
1964
1965/**
1966 * \brief Set the color mode for the specified DataSet
1967 */
1968void Renderer::setPseudoColorColorMode(const DataSetId& id,
1969                                       PseudoColor::ColorMode mode,
1970                                       DataSet::DataAttributeType type,
1971                                       const char *name, double range[2])
1972{
1973    PseudoColorHashmap::iterator itr;
1974
1975    bool doAll = false;
1976
1977    if (id.compare("all") == 0) {
1978        itr = _pseudoColors.begin();
1979        doAll = true;
1980    } else {
1981        itr = _pseudoColors.find(id);
1982    }
1983    if (itr == _pseudoColors.end()) {
1984        ERROR("PseudoColor not found: %s", id.c_str());
1985        return;
1986    }
1987
1988    do {
1989        itr->second->setColorMode(mode, type, name, range);
1990    } while (doAll && ++itr != _pseudoColors.end());
1991
1992    _needsRedraw = true;
1993}
1994
1995/**
1996 * \brief Set the color mode for the specified DataSet
1997 */
1998void Renderer::setPseudoColorColorMode(const DataSetId& id,
1999                                       PseudoColor::ColorMode mode,
2000                                       const char *name, double range[2])
2001{
2002    PseudoColorHashmap::iterator itr;
2003
2004    bool doAll = false;
2005
2006    if (id.compare("all") == 0) {
2007        itr = _pseudoColors.begin();
2008        doAll = true;
2009    } else {
2010        itr = _pseudoColors.find(id);
2011    }
2012    if (itr == _pseudoColors.end()) {
2013        ERROR("PseudoColor not found: %s", id.c_str());
2014        return;
2015    }
2016
2017    do {
2018        itr->second->setColorMode(mode, name, range);
2019    } while (doAll && ++itr != _pseudoColors.end());
2020
2021    _needsRedraw = true;
2022}
2023
2024/**
2025 * \brief Set Sphere resolution
2026 */
2027void Renderer::setSphereResolution(const DataSetId& id, int thetaRes, int phiRes)
2028{
2029    SphereHashmap::iterator itr;
2030
2031    bool doAll = false;
2032
2033    if (id.compare("all") == 0) {
2034        itr = _spheres.begin();
2035        doAll = true;
2036    } else {
2037        itr = _spheres.find(id);
2038    }
2039    if (itr == _spheres.end()) {
2040        ERROR("Sphere not found: %s", id.c_str());
2041        return;
2042    }
2043
2044    do {
2045        itr->second->setThetaResolution(thetaRes);
2046        itr->second->setPhiResolution(phiRes);
2047    } while (doAll && ++itr != _spheres.end());
2048
2049    _needsRedraw = true;
2050}
2051
2052/**
2053 * \brief Set Sphere section
2054 */
2055void Renderer::setSphereSection(const DataSetId& id, double thetaStart, double thetaEnd,
2056                                double phiStart, double phiEnd)
2057{
2058    SphereHashmap::iterator itr;
2059
2060    bool doAll = false;
2061
2062    if (id.compare("all") == 0) {
2063        itr = _spheres.begin();
2064        doAll = true;
2065    } else {
2066        itr = _spheres.find(id);
2067    }
2068    if (itr == _spheres.end()) {
2069        ERROR("Sphere not found: %s", id.c_str());
2070        return;
2071    }
2072
2073    do {
2074        itr->second->setStartTheta(thetaStart);
2075        itr->second->setEndTheta(thetaEnd);
2076        itr->second->setStartPhi(phiStart);
2077        itr->second->setEndPhi(phiEnd);
2078    } while (doAll && ++itr != _spheres.end());
2079
2080    _needsRedraw = true;
2081}
2082
2083/**
2084 * \brief Set the streamlines seed to points of the streamlines DataSet
2085 */
2086void Renderer::setStreamlinesNumberOfSeedPoints(const DataSetId& id, int numPoints)
2087{
2088    StreamlinesHashmap::iterator itr;
2089
2090    bool doAll = false;
2091
2092    if (id.compare("all") == 0) {
2093        itr = _streamlines.begin();
2094        doAll = true;
2095    } else {
2096        itr = _streamlines.find(id);
2097    }
2098    if (itr == _streamlines.end()) {
2099        ERROR("Streamlines not found: %s", id.c_str());
2100        return;
2101    }
2102
2103    do {
2104        itr->second->setNumberOfSeedPoints(numPoints);
2105    } while (doAll && ++itr != _streamlines.end());
2106
2107    _needsRedraw = true;
2108}
2109
2110/**
2111 * \brief Set the streamlines seed to points of the streamlines DataSet
2112 */
2113void Renderer::setStreamlinesSeedToMeshPoints(const DataSetId& id)
2114{
2115    StreamlinesHashmap::iterator itr;
2116
2117    bool doAll = false;
2118
2119    if (id.compare("all") == 0) {
2120        itr = _streamlines.begin();
2121        doAll = true;
2122    } else {
2123        itr = _streamlines.find(id);
2124    }
2125    if (itr == _streamlines.end()) {
2126        ERROR("Streamlines not found: %s", id.c_str());
2127        return;
2128    }
2129
2130    do {
2131        itr->second->setSeedToMeshPoints();
2132    } while (doAll && ++itr != _streamlines.end());
2133
2134    _needsRedraw = true;
2135}
2136
2137/**
2138 * \brief Set the streamlines seed to points distributed randomly inside
2139 * cells of the streamlines DataSet
2140 */
2141void Renderer::setStreamlinesSeedToFilledMesh(const DataSetId& id, int numPoints)
2142{
2143    StreamlinesHashmap::iterator itr;
2144
2145    bool doAll = false;
2146
2147    if (id.compare("all") == 0) {
2148        itr = _streamlines.begin();
2149        doAll = true;
2150    } else {
2151        itr = _streamlines.find(id);
2152    }
2153    if (itr == _streamlines.end()) {
2154        ERROR("Streamlines not found: %s", id.c_str());
2155        return;
2156    }
2157
2158    do {
2159        itr->second->setSeedToFilledMesh(numPoints);
2160    } while (doAll && ++itr != _streamlines.end());
2161
2162    _needsRedraw = true;
2163}
2164
2165/**
2166 * \brief Set the streamlines seed to points of a DataSet
2167 *
2168 * \param[in] id DataSet identifier
2169 * \param[in] data Bytes of VTK DataSet file
2170 * \param[in] nbytes Length of data array
2171 *
2172 * \return boolean indicating success or failure
2173 */
2174bool Renderer::setStreamlinesSeedToMeshPoints(const DataSetId& id,
2175                                              char *data, size_t nbytes)
2176{
2177    vtkSmartPointer<vtkDataSetReader> reader = vtkSmartPointer<vtkDataSetReader>::New();
2178    vtkSmartPointer<vtkCharArray> dataSetString = vtkSmartPointer<vtkCharArray>::New();
2179
2180    dataSetString->SetArray(data, nbytes, 1);
2181    reader->SetInputArray(dataSetString);
2182    reader->ReadFromInputStringOn();
2183    reader->Update();
2184
2185    vtkSmartPointer<vtkDataSet> dataSet = reader->GetOutput();
2186    if (dataSet == NULL) {
2187        return false;
2188    }
2189#ifndef USE_VTK6
2190    dataSet->SetPipelineInformation(NULL);
2191#endif
2192    StreamlinesHashmap::iterator itr;
2193
2194    bool doAll = false;
2195
2196    if (id.compare("all") == 0) {
2197        itr = _streamlines.begin();
2198        doAll = true;
2199    } else {
2200        itr = _streamlines.find(id);
2201    }
2202    if (itr == _streamlines.end()) {
2203        ERROR("Streamlines not found: %s", id.c_str());
2204        return false;
2205    }
2206
2207    do {
2208        itr->second->setSeedToMeshPoints(dataSet);
2209    } while (doAll && ++itr != _streamlines.end());
2210
2211    _needsRedraw = true;
2212    return true;
2213}
2214
2215/**
2216 * \brief Set the streamlines seed to points distributed randomly inside
2217 * cells of DataSet
2218 *
2219 * \param[in] id DataSet identifier
2220 * \param[in] data Bytes of VTK DataSet file
2221 * \param[in] nbytes Length of data array
2222 * \param[in] numPoints Number of random seed points to generate
2223 *
2224 * \return boolean indicating success or failure
2225 */
2226bool Renderer::setStreamlinesSeedToFilledMesh(const DataSetId& id,
2227                                              char *data, size_t nbytes,
2228                                              int numPoints)
2229{
2230    vtkSmartPointer<vtkDataSetReader> reader = vtkSmartPointer<vtkDataSetReader>::New();
2231    vtkSmartPointer<vtkCharArray> dataSetString = vtkSmartPointer<vtkCharArray>::New();
2232
2233    dataSetString->SetArray(data, nbytes, 1);
2234    reader->SetInputArray(dataSetString);
2235    reader->ReadFromInputStringOn();
2236    reader->Update();
2237
2238    vtkSmartPointer<vtkDataSet> dataSet = reader->GetOutput();
2239    if (dataSet == NULL) {
2240        return false;
2241    }
2242#ifndef USE_VTK6
2243    dataSet->SetPipelineInformation(NULL);
2244#endif
2245    StreamlinesHashmap::iterator itr;
2246
2247    bool doAll = false;
2248
2249    if (id.compare("all") == 0) {
2250        itr = _streamlines.begin();
2251        doAll = true;
2252    } else {
2253        itr = _streamlines.find(id);
2254    }
2255    if (itr == _streamlines.end()) {
2256        ERROR("Streamlines not found: %s", id.c_str());
2257        return false;
2258    }
2259
2260    do {
2261        itr->second->setSeedToFilledMesh(dataSet, numPoints);
2262    } while (doAll && ++itr != _streamlines.end());
2263
2264    _needsRedraw = true;
2265    return true;
2266}
2267
2268/**
2269 * \brief Set the streamlines seed to points along a line
2270 */
2271void Renderer::setStreamlinesSeedToRake(const DataSetId& id,
2272                                        double start[3], double end[3],
2273                                        int numPoints)
2274{
2275    StreamlinesHashmap::iterator itr;
2276
2277    bool doAll = false;
2278
2279    if (id.compare("all") == 0) {
2280        itr = _streamlines.begin();
2281        doAll = true;
2282    } else {
2283        itr = _streamlines.find(id);
2284    }
2285    if (itr == _streamlines.end()) {
2286        ERROR("Streamlines not found: %s", id.c_str());
2287        return;
2288    }
2289
2290    do {
2291        itr->second->setSeedToRake(start, end, numPoints);
2292    } while (doAll && ++itr != _streamlines.end());
2293
2294    _needsRedraw = true;
2295}
2296
2297/**
2298 * \brief Set the streamlines seed to points inside a disk, with optional
2299 * hole
2300 */
2301void Renderer::setStreamlinesSeedToDisk(const DataSetId& id,
2302                                        double center[3], double normal[3],
2303                                        double radius, double innerRadius,
2304                                        int numPoints)
2305{
2306    StreamlinesHashmap::iterator itr;
2307
2308    bool doAll = false;
2309
2310    if (id.compare("all") == 0) {
2311        itr = _streamlines.begin();
2312        doAll = true;
2313    } else {
2314        itr = _streamlines.find(id);
2315    }
2316    if (itr == _streamlines.end()) {
2317        ERROR("Streamlines not found: %s", id.c_str());
2318        return;
2319    }
2320
2321    do {
2322        itr->second->setSeedToDisk(center, normal, radius, innerRadius, numPoints);
2323    } while (doAll && ++itr != _streamlines.end());
2324
2325    _needsRedraw = true;
2326}
2327
2328/**
2329 * \brief Set the streamlines seed to vertices of an n-sided polygon
2330 */
2331void Renderer::setStreamlinesSeedToPolygon(const DataSetId& id,
2332                                           double center[3], double normal[3],
2333                                           double angle, double radius,
2334                                           int numSides)
2335{
2336    StreamlinesHashmap::iterator itr;
2337
2338    bool doAll = false;
2339
2340    if (id.compare("all") == 0) {
2341        itr = _streamlines.begin();
2342        doAll = true;
2343    } else {
2344        itr = _streamlines.find(id);
2345    }
2346    if (itr == _streamlines.end()) {
2347        ERROR("Streamlines not found: %s", id.c_str());
2348        return;
2349    }
2350
2351    do {
2352        itr->second->setSeedToPolygon(center, normal, angle, radius, numSides);
2353    } while (doAll && ++itr != _streamlines.end());
2354
2355    _needsRedraw = true;
2356}
2357
2358/**
2359 * \brief Set the streamlines seed to vertices of an n-sided polygon
2360 */
2361void Renderer::setStreamlinesSeedToFilledPolygon(const DataSetId& id,
2362                                                 double center[3],
2363                                                 double normal[3],
2364                                                 double angle, double radius,
2365                                                 int numSides, int numPoints)
2366{
2367    StreamlinesHashmap::iterator itr;
2368
2369    bool doAll = false;
2370
2371    if (id.compare("all") == 0) {
2372        itr = _streamlines.begin();
2373        doAll = true;
2374    } else {
2375        itr = _streamlines.find(id);
2376    }
2377    if (itr == _streamlines.end()) {
2378        ERROR("Streamlines not found: %s", id.c_str());
2379        return;
2380    }
2381
2382    do {
2383        itr->second->setSeedToFilledPolygon(center, normal, angle,
2384                                            radius, numSides, numPoints);
2385    } while (doAll && ++itr != _streamlines.end());
2386
2387    _needsRedraw = true;
2388}
2389
2390/**
2391 * \brief Set Streamlines rendering to polylines for the specified DataSet
2392 */
2393void Renderer::setStreamlinesTypeToLines(const DataSetId& id)
2394{
2395    StreamlinesHashmap::iterator itr;
2396
2397    bool doAll = false;
2398
2399    if (id.compare("all") == 0) {
2400        itr = _streamlines.begin();
2401        doAll = true;
2402    } else {
2403        itr = _streamlines.find(id);
2404    }
2405    if (itr == _streamlines.end()) {
2406        ERROR("Streamlines not found: %s", id.c_str());
2407        return;
2408    }
2409
2410    do {
2411        itr->second->setLineTypeToLines();
2412    } while (doAll && ++itr != _streamlines.end());
2413
2414    _needsRedraw = true;
2415}
2416
2417/**
2418 * \brief Set Streamlines rendering to tubes for the specified DataSet
2419 */
2420void Renderer::setStreamlinesTypeToTubes(const DataSetId& id, int numSides, double radius)
2421{
2422    StreamlinesHashmap::iterator itr;
2423
2424    bool doAll = false;
2425
2426    if (id.compare("all") == 0) {
2427        itr = _streamlines.begin();
2428        doAll = true;
2429    } else {
2430        itr = _streamlines.find(id);
2431    }
2432    if (itr == _streamlines.end()) {
2433        ERROR("Streamlines not found: %s", id.c_str());
2434        return;
2435    }
2436
2437    do {
2438        itr->second->setLineTypeToTubes(numSides, radius);
2439    } while (doAll && ++itr != _streamlines.end());
2440
2441    _needsRedraw = true;
2442}
2443
2444/**
2445 * \brief Set Streamlines rendering to ribbons for the specified DataSet
2446 */
2447void Renderer::setStreamlinesTypeToRibbons(const DataSetId& id, double width, double angle)
2448{
2449    StreamlinesHashmap::iterator itr;
2450
2451    bool doAll = false;
2452
2453    if (id.compare("all") == 0) {
2454        itr = _streamlines.begin();
2455        doAll = true;
2456    } else {
2457        itr = _streamlines.find(id);
2458    }
2459    if (itr == _streamlines.end()) {
2460        ERROR("Streamlines not found: %s", id.c_str());
2461        return;
2462    }
2463
2464    do {
2465        itr->second->setLineTypeToRibbons(width, angle);
2466    } while (doAll && ++itr != _streamlines.end());
2467
2468    _needsRedraw = true;
2469}
2470
2471/**
2472 * \brief Set Streamlines maximum length for the specified DataSet
2473 */
2474void Renderer::setStreamlinesLength(const DataSetId& id, double length)
2475{
2476    StreamlinesHashmap::iterator itr;
2477
2478    bool doAll = false;
2479
2480    if (id.compare("all") == 0) {
2481        itr = _streamlines.begin();
2482        doAll = true;
2483    } else {
2484        itr = _streamlines.find(id);
2485    }
2486    if (itr == _streamlines.end()) {
2487        ERROR("Streamlines not found: %s", id.c_str());
2488        return;
2489    }
2490
2491    do {
2492        itr->second->setMaxPropagation(length);
2493    } while (doAll && ++itr != _streamlines.end());
2494
2495    _needsRedraw = true;
2496}
2497
2498/**
2499 * \brief Turn on/off rendering of the Streamlines seed geometry for the given DataSet
2500 */
2501void Renderer::setStreamlinesSeedVisibility(const DataSetId& id, bool state)
2502{
2503    StreamlinesHashmap::iterator itr;
2504
2505    bool doAll = false;
2506
2507    if (id.compare("all") == 0) {
2508        itr = _streamlines.begin();
2509        doAll = true;
2510    } else {
2511        itr = _streamlines.find(id);
2512    }
2513    if (itr == _streamlines.end()) {
2514        ERROR("Streamlines not found: %s", id.c_str());
2515        return;
2516    }
2517
2518    do {
2519        itr->second->setSeedVisibility(state);
2520    } while (doAll && ++itr != _streamlines.end());
2521
2522    _needsRedraw = true;
2523}
2524
2525/**
2526 * \brief Set the color mode for the specified DataSet
2527 */
2528void Renderer::setStreamlinesColorMode(const DataSetId& id,
2529                                       Streamlines::ColorMode mode,
2530                                       DataSet::DataAttributeType type,
2531                                       const char *name, double range[2])
2532{
2533    StreamlinesHashmap::iterator itr;
2534
2535    bool doAll = false;
2536
2537    if (id.compare("all") == 0) {
2538        itr = _streamlines.begin();
2539        doAll = true;
2540    } else {
2541        itr = _streamlines.find(id);
2542    }
2543    if (itr == _streamlines.end()) {
2544        ERROR("Streamlines not found: %s", id.c_str());
2545        return;
2546    }
2547
2548    do {
2549        itr->second->setColorMode(mode, type, name, range);
2550    } while (doAll && ++itr != _streamlines.end());
2551
2552    _needsRedraw = true;
2553}
2554
2555/**
2556 * \brief Set the color mode for the specified DataSet
2557 */
2558void Renderer::setStreamlinesColorMode(const DataSetId& id,
2559                                       Streamlines::ColorMode mode,
2560                                       const char *name, double range[2])
2561{
2562    StreamlinesHashmap::iterator itr;
2563
2564    bool doAll = false;
2565
2566    if (id.compare("all") == 0) {
2567        itr = _streamlines.begin();
2568        doAll = true;
2569    } else {
2570        itr = _streamlines.find(id);
2571    }
2572    if (itr == _streamlines.end()) {
2573        ERROR("Streamlines not found: %s", id.c_str());
2574        return;
2575    }
2576
2577    do {
2578        itr->second->setColorMode(mode, name, range);
2579    } while (doAll && ++itr != _streamlines.end());
2580
2581    _needsRedraw = true;
2582}
2583
2584/**
2585 * \brief Set the RGB line/edge color for the specified DataSet
2586 */
2587void Renderer::setStreamlinesSeedColor(const DataSetId& id, float color[3])
2588{
2589    StreamlinesHashmap::iterator itr;
2590
2591    bool doAll = false;
2592
2593    if (id.compare("all") == 0) {
2594        itr = _streamlines.begin();
2595        doAll = true;
2596    } else {
2597        itr = _streamlines.find(id);
2598    }
2599    if (itr == _streamlines.end()) {
2600        ERROR("Streamlines not found: %s", id.c_str());
2601        return;
2602    }
2603
2604    do {
2605        itr->second->setSeedColor(color);
2606    } while (doAll && ++itr != _streamlines.end());
2607
2608    _needsRedraw = true;
2609}
2610
2611/**
2612 * \brief Set the sample rate for the volume shader
2613 *
2614 * Smaller values will give better rendering at the cost
2615 * of slower rendering
2616 */
2617void Renderer::setVolumeSampleDistance(const DataSetId& id, double distance)
2618{
2619    VolumeHashmap::iterator itr;
2620
2621    bool doAll = false;
2622
2623    if (id.compare("all") == 0) {
2624        itr = _volumes.begin();
2625        doAll = true;
2626    } else {
2627        itr = _volumes.find(id);
2628    }
2629    if (itr == _volumes.end()) {
2630        ERROR("Volume not found: %s", id.c_str());
2631        return;
2632    }
2633
2634    do {
2635        distance *= itr->second->getAverageSpacing();
2636        itr->second->setSampleDistance((float)distance);
2637    } while (doAll && ++itr != _volumes.end());
2638
2639    _needsRedraw = true;
2640}
2641
2642/**
2643 * \brief Set amount to scale vector magnitudes when warping
2644 * a mesh
2645 */
2646void Renderer::setWarpWarpScale(const DataSetId& id, double scale)
2647{
2648    WarpHashmap::iterator itr;
2649
2650    bool doAll = false;
2651
2652    if (id.compare("all") == 0) {
2653        itr = _warps.begin();
2654        doAll = true;
2655    } else {
2656        itr = _warps.find(id);
2657    }
2658
2659    if (itr == _warps.end()) {
2660        ERROR("Warp not found: %s", id.c_str());
2661        return;
2662    }
2663
2664    do {
2665        itr->second->setWarpScale(scale);
2666     } while (doAll && ++itr != _warps.end());
2667
2668    _renderer->ResetCameraClippingRange();
2669    resetAxes();
2670    _needsRedraw = true;
2671}
Note: See TracBrowser for help on using the repository browser.