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

Last change on this file since 3621 was 3621, checked in by ldelgass, 12 years ago

Some more renaming: remove Vtk from some filenames and rename VtkGraphicsObject?
to GraphicsObject? to avoid confusion with vtk classes.

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