source: trunk/packages/vizservers/vtkvis/GraphicsObject.h @ 3778

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

Add image actor support

  • Property svn:eol-style set to native
File size: 31.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#ifndef VTKVIS_GRAPHICS_OBJECT_H
9#define VTKVIS_GRAPHICS_OBJECT_H
10
11#include <cmath>
12#include <string>
13
14#include <vtkSmartPointer.h>
15#include <vtkProp.h>
16#include <vtkActor2D.h>
17#include <vtkProp3D.h>
18#include <vtkProp3DCollection.h>
19#include <vtkAssembly.h>
20#include <vtkActor.h>
21#include <vtkImageActor.h>
22#include <vtkVolume.h>
23#include <vtkProperty.h>
24#include <vtkImageProperty.h>
25#include <vtkVolumeProperty.h>
26#include <vtkMath.h>
27#include <vtkMatrix4x4.h>
28#include <vtkPlaneCollection.h>
29
30#include "DataSet.h"
31#include "Trace.h"
32
33namespace VtkVis {
34
35class Renderer;
36
37/**
38 * \brief Base class for graphics objects
39 */
40class GraphicsObject {
41public:
42    enum CullFace {
43        CULL_FRONT,
44        CULL_BACK,
45        CULL_FRONT_AND_BACK
46    };
47    enum ShadingModel {
48        SHADE_FLAT = VTK_FLAT,
49        SHADE_GOURAUD = VTK_GOURAUD,
50        SHADE_PHONG = VTK_PHONG
51    };
52
53    GraphicsObject() :
54        _dataSet(NULL),
55        _opacity(1.0),
56        _edgeWidth(1.0f),
57        _pointSize(1.0f),
58        _lighting(true),
59        _cullFace(CULL_BACK),
60        _faceCulling(false)
61    {
62        _dataRange[0] = 0;
63        _dataRange[1] = 1;
64        _color[0] = 1.0f;
65        _color[1] = 1.0f;
66        _color[2] = 1.0f;
67        _edgeColor[0] = 0.0f;
68        _edgeColor[1] = 0.0f;
69        _edgeColor[2] = 0.0f;
70    }
71
72    virtual ~GraphicsObject()
73    {}
74
75    /**
76     * \brief Return the name of the sublass of GraphicsObject
77     */
78    virtual const char *getClassName() const = 0;
79
80    /**
81     * \brief Specify input DataSet and information on cumulative data ranges
82     *
83     * Default implementation calls update() and stores scalarRange to
84     * _dataRange based on cumulative range settings
85     *
86     * \param[in] dataSet DataSet to use in rendering
87     * \param[in] renderer Pointer to Renderer -- may be used to get
88     * cumulative data ranges
89     */
90    virtual void setDataSet(DataSet *dataSet,
91                            Renderer *renderer);
92
93    /**
94     * \brief Called when scalar or vector field changes (e.g. active field) or
95     * cumulative ranges or settings change
96     *
97     * \param[in] renderer Pointer to Renderer -- may be used to get
98     * cumulative data ranges
99     */
100    virtual void updateRanges(Renderer *renderer);
101
102    /**
103     * \brief Return the DataSet this object renders
104     */
105    inline DataSet *getDataSet()
106    {
107        return _dataSet;
108    }
109
110    /**
111     * \brief Return the VTK prop object to render
112     */
113    inline vtkProp *getProp()
114    {
115        return _prop;
116    }
117
118    /**
119     * \brief Cast the vktProp to a vtkActor2D
120     *
121     * \return NULL or a vtkActor2D pointer
122     */
123    inline vtkActor2D *getActor2D()
124    {
125        return vtkActor2D::SafeDownCast(_prop);
126    }
127
128    /**
129     * \brief Cast the vktProp to a vtkProp3D
130     *
131     * \return NULL or a vtkProp3D pointer
132     */
133    inline vtkProp3D *getProp3D()
134    {
135        return vtkProp3D::SafeDownCast(_prop);
136    }
137
138    /**
139     * \brief Cast the vktProp to a vtkActor
140     *
141     * \return NULL or a vtkActor pointer
142     */
143    inline vtkActor *getActor()
144    {
145        return vtkActor::SafeDownCast(_prop);
146    }
147
148    /**
149     * \brief Cast the vktProp to a vtkImageActor
150     *
151     * \return NULL or a vtkImageActor pointer
152     */
153    inline vtkImageActor *getImageActor()
154    {
155        return vtkImageActor::SafeDownCast(_prop);
156    }
157
158    /**
159     * \brief Cast the vktProp to a vtkVolume
160     *
161     * \return NULL or a vtkVolume pointer
162     */
163    inline vtkVolume *getVolume()
164    {
165        return vtkVolume::SafeDownCast(_prop);
166    }
167
168    /**
169     * \brief Cast the vktProp to a vtkAssembly
170     *
171     * \return NULL or a vtkAssembly pointer
172     */
173    inline vtkAssembly *getAssembly()
174    {
175        return vtkAssembly::SafeDownCast(_prop);
176    }
177
178    /**
179     * \brief If the object has a 2D overlay prop, return it
180     *
181     * \return NULL or a vtkProp pointer
182     */
183    virtual vtkProp *getOverlayProp()
184    {
185        return NULL;
186    }
187
188    /**
189     * \brief Set an additional transform on the prop
190     *
191     * prop must be a vtkProp3D.  The transform is
192     * concatenated with the internal transform created
193     * by setting the prop position, orientation and scale
194     */
195    virtual void setTransform(vtkMatrix4x4 *matrix)
196    {
197        if (getProp3D() != NULL) {
198            getProp3D()->SetUserMatrix(matrix);
199        }
200    }
201
202    /**
203     * \brief Set the prop center of rotation
204     *
205     * \param[in] origin The point about which the object rotates
206     */
207    virtual void setOrigin(double origin[3])
208    {
209        if (getProp3D() != NULL) {
210            getProp3D()->SetOrigin(origin);
211        }
212    }
213
214    /**
215     * \brief Set the prop orientation with a quaternion
216     *
217     * \param[in] quat Quaternion with scalar part first
218     */
219    virtual void setOrientation(double quat[4])
220    {
221        if (getProp3D() != NULL) {
222            double angle = vtkMath::DegreesFromRadians(2.0 * acos(quat[0]));
223            double axis[3];
224            if (angle < 1.0e-6) {
225                axis[0] = 1;
226                axis[1] = 0;
227                axis[2] = 0;
228            } else {
229                double denom = sqrt(1. - quat[0] * quat[0]);
230                axis[0] = quat[1] / denom;
231                axis[1] = quat[2] / denom;
232                axis[2] = quat[3] / denom;
233            }
234            setOrientation(angle, axis);
235        }
236    }
237
238    /**
239     * \brief Set the prop orientation with a rotation about an axis
240     *
241     * \param[in] angle Angle in degrees
242     * \param[in] axis Axis of rotation
243     */
244    virtual void setOrientation(double angle, double axis[3])
245    {
246        if (getProp3D() != NULL) {
247            getProp3D()->SetOrientation(0, 0, 0);
248            getProp3D()->RotateWXYZ(angle, axis[0], axis[1], axis[2]);
249        }
250    }
251
252    /**
253     * \brief Set the prop position
254     *
255     * \param[in] pos Position in world coordinates
256     */
257    virtual void setPosition(double pos[3])
258    {
259        if (getProp3D() != NULL) {
260            getProp3D()->SetPosition(pos);
261        }
262    }
263
264    /**
265     * \brief Set 2D aspect ratio scaling
266     *
267     * \param aspect 0=no scaling, otherwise aspect
268     * is horiz/vertical ratio
269     */
270    virtual void setAspect(double aspect)
271    {
272        double scale[3];
273        scale[0] = scale[1] = scale[2] = 1.;
274
275        if (aspect == 0.0) {
276            setScale(scale);
277            return;
278        }
279        if (_dataSet == NULL ||
280            _dataSet->getVtkDataSet() == NULL) {
281            TRACE("Not setting aspect for object with no data set");
282            return;
283        }
284
285        PrincipalPlane plane;
286        if (!_dataSet->is2D(&plane)) {
287            TRACE("Not setting aspect for 3D object");
288            return;
289        }
290
291        double bounds[6];
292        vtkDataSet *ds = _dataSet->getVtkDataSet();
293        ds->GetBounds(bounds);
294        double size[3];
295        size[0] = bounds[1] - bounds[0];
296        size[1] = bounds[3] - bounds[2];
297        size[2] = bounds[5] - bounds[4];
298
299        if (aspect == 1.0) {
300            // Square
301            switch (plane) {
302            case PLANE_XY: {
303                if (size[0] > size[1] && size[1] > 1.0e-6) {
304                    scale[1] = size[0] / size[1];
305                } else if (size[1] > size[0] && size[0] > 1.0e-6) {
306                    scale[0] = size[1] / size[0];
307                }
308            }
309                break;
310            case PLANE_ZY: {
311                if (size[1] > size[2] && size[2] > 1.0e-6) {
312                    scale[2] = size[1] / size[2];
313                } else if (size[2] > size[1] && size[1] > 1.0e-6) {
314                    scale[1] = size[2] / size[1];
315                }
316            }
317                break;
318            case PLANE_XZ: {
319                if (size[0] > size[2] && size[2] > 1.0e-6) {
320                    scale[2] = size[0] / size[2];
321                } else if (size[2] > size[0] && size[0] > 1.0e-6) {
322                    scale[0] = size[2] / size[0];
323                }
324            }
325                break;
326            default:
327                break;
328            }
329        } else {
330            switch (plane) {
331            case PLANE_XY: {
332                if (aspect > 1.0) {
333                    if (size[0] > size[1]) {
334                        scale[1] = (size[0] / aspect) / size[1];
335                    } else {
336                        scale[0] = (size[1] * aspect) / size[0];
337                    }
338                } else {
339                    if (size[1] > size[0]) {
340                        scale[0] = (size[1] * aspect) / size[0];
341                    } else {
342                        scale[1] = (size[0] / aspect) / size[1];
343                    }
344                }
345            }
346                break;
347            case PLANE_ZY: {
348                if (aspect > 1.0) {
349                    if (size[2] > size[1]) {
350                        scale[1] = (size[2] / aspect) / size[1];
351                    } else {
352                        scale[2] = (size[1] * aspect) / size[2];
353                    }
354                } else {
355                    if (size[1] > size[2]) {
356                        scale[2] = (size[1] * aspect) / size[2];
357                    } else {
358                        scale[1] = (size[2] / aspect) / size[1];
359                    }
360                }
361            }
362                break;
363            case PLANE_XZ: {
364                if (aspect > 1.0) {
365                    if (size[0] > size[2]) {
366                        scale[2] = (size[0] / aspect) / size[2];
367                    } else {
368                        scale[0] = (size[2] * aspect) / size[0];
369                    }
370                } else {
371                    if (size[2] > size[0]) {
372                        scale[0] = (size[2] * aspect) / size[0];
373                    } else {
374                        scale[2] = (size[0] / aspect) / size[2];
375                    }
376                }
377            }
378            default:
379                break;
380            }
381        }
382
383        TRACE("obj %g,%g,%g", size[0], size[1], size[2]);
384        TRACE("Setting scale to %g,%g,%g", scale[0], scale[1], scale[2]);
385        setScale(scale);
386    }
387
388    /**
389     * \brief Get the prop scaling
390     *
391     * \param[out] scale Scaling in x,y,z
392     */
393    virtual void getScale(double scale[3])
394    {
395        if (getProp3D() != NULL) {
396            getProp3D()->GetScale(scale);
397        } else {
398            scale[0] = scale[1] = scale[2] = 1.0;
399        }
400    }
401
402    /**
403     * \brief Set the prop scaling
404     *
405     * \param[in] scale Scaling in x,y,z
406     */
407    virtual void setScale(double scale[3])
408    {
409        if (getProp3D() != NULL) {
410            getProp3D()->SetScale(scale);
411        }
412    }
413
414    /**
415     * \brief Get the physical bounds of the prop
416     *
417     * If the prop is scaled, these bounds will be
418     * scaled as well
419     */
420    virtual double *getBounds()
421    {
422        if (getProp() != NULL)
423            return getProp()->GetBounds();
424        else
425            return NULL;
426    }
427
428    /**
429     * \brief Get the data bounds of the prop
430     *
431     * If the prop is scaled, these bounds will NOT
432     * be scaled, they will reflect the unscaled data
433     * bounds.
434     */
435    virtual double *getUnscaledBounds()
436    {
437        if (getProp3D() != NULL) {
438            double scale[3];
439            getProp3D()->GetScale(scale);
440            if (scale[0] == scale[1] && scale[1] == scale[2] &&
441                scale[0] == 1.0) {
442                return getBounds();
443            } else if (getBounds() != NULL) {
444                _unscaledBounds[0] = getBounds()[0] / scale[0];
445                _unscaledBounds[1] = getBounds()[1] / scale[0];
446                _unscaledBounds[2] = getBounds()[2] / scale[1];
447                _unscaledBounds[3] = getBounds()[3] / scale[1];
448                _unscaledBounds[4] = getBounds()[4] / scale[2];
449                _unscaledBounds[5] = getBounds()[5] / scale[2];
450                return _unscaledBounds;
451            }
452        }
453        return getBounds();
454    }
455
456    /**
457     * \brief Toggle visibility of the prop
458     */
459    virtual void setVisibility(bool state)
460    {
461        if (_prop != NULL)
462            _prop->SetVisibility((state ? 1 : 0));
463    }
464
465    /**
466     * \brief Get visibility state of the prop
467     */
468    virtual bool getVisibility()
469    {
470        if (_prop != NULL &&
471            _prop->GetVisibility() != 0) {
472            return true;
473        } else {
474            return false;
475        }
476    }
477
478    /**
479     * \brief Set the opacity of the object
480     *
481     * The prop must be a vtkActor or vtkAssembly
482     */
483    virtual void setOpacity(double opacity)
484    {
485        _opacity = opacity;
486        if (getActor() != NULL) {
487            getActor()->GetProperty()->SetOpacity(opacity);
488            if (_faceCulling && _opacity < 1.0) {
489                setCulling(getActor()->GetProperty(), false);
490                TRACE("Culling off");
491            } else if (_faceCulling && _opacity == 1.0) {
492                setCulling(getActor()->GetProperty(), true);
493                TRACE("Culling on");
494            }
495        } else if (getAssembly() != NULL) {
496            vtkProp3DCollection *props = getAssembly()->GetParts();
497            vtkProp3D *prop;
498            props->InitTraversal();
499            while ((prop = props->GetNextProp3D()) != NULL) {
500                if (vtkActor::SafeDownCast(prop) != NULL) {
501                    vtkActor::SafeDownCast(prop)->GetProperty()->SetOpacity(opacity);
502                    if (_faceCulling && _opacity < 1.0) {
503                        setCulling(vtkActor::SafeDownCast(prop)->GetProperty(), false);
504                        TRACE("Culling off");
505                    } else if (_faceCulling && _opacity == 1.0) {
506                        setCulling(vtkActor::SafeDownCast(prop)->GetProperty(), true);
507                        TRACE("Culling on");
508                    }
509                } else if (vtkImageActor::SafeDownCast(prop) != NULL) {
510                    vtkImageActor::SafeDownCast(prop)->GetProperty()->SetOpacity(opacity);
511                }
512            }
513        } else if (getImageActor() != NULL) {
514            getImageActor()->GetProperty()->SetOpacity(_opacity);
515        }
516    }
517
518    /**
519     * \brief Get the opacity of the object
520     */
521    inline double getOpacity()
522    {
523        return _opacity;
524    }
525
526    /**
527     * \brief Set the ambient material coefficient
528     */
529    virtual void setAmbient(double ambient)
530    {
531        if (getActor() != NULL) {
532            getActor()->GetProperty()->SetAmbient(ambient);
533        } else if (getImageActor() != NULL) {
534            getImageActor()->GetProperty()->SetAmbient(ambient);
535        } else if (getVolume() != NULL) {
536            getVolume()->GetProperty()->SetAmbient(ambient);
537        } else if (getAssembly() != NULL) {
538            vtkProp3DCollection *props = getAssembly()->GetParts();
539            vtkProp3D *prop;
540            props->InitTraversal();
541            while ((prop = props->GetNextProp3D()) != NULL) {
542                if (vtkActor::SafeDownCast(prop) != NULL) {
543                    vtkActor::SafeDownCast(prop)->GetProperty()->SetAmbient(ambient);
544                } else if (vtkImageActor::SafeDownCast(prop) != NULL) {
545                    vtkImageActor::SafeDownCast(prop)->GetProperty()->SetAmbient(ambient);
546                } else if (vtkVolume::SafeDownCast(prop) != NULL) {
547                    vtkVolume::SafeDownCast(prop)->GetProperty()->SetAmbient(ambient);
548                }
549            }
550        }
551    }
552
553    /**
554     * \brief Set the diffuse material coefficient
555     */
556    virtual void setDiffuse(double diffuse)
557    {
558        if (getActor() != NULL) {
559            getActor()->GetProperty()->SetDiffuse(diffuse);
560        } else if (getImageActor() != NULL) {
561            getImageActor()->GetProperty()->SetDiffuse(diffuse);
562        } else if (getVolume() != NULL) {
563            getVolume()->GetProperty()->SetDiffuse(diffuse);
564        } else if (getAssembly() != NULL) {
565            vtkProp3DCollection *props = getAssembly()->GetParts();
566            vtkProp3D *prop;
567            props->InitTraversal();
568            while ((prop = props->GetNextProp3D()) != NULL) {
569                if (vtkActor::SafeDownCast(prop) != NULL) {
570                    vtkActor::SafeDownCast(prop)->GetProperty()->SetDiffuse(diffuse);
571                } else if (vtkImageActor::SafeDownCast(prop) != NULL) {
572                    vtkImageActor::SafeDownCast(prop)->GetProperty()->SetDiffuse(diffuse);
573                } else if (vtkVolume::SafeDownCast(prop) != NULL) {
574                    vtkVolume::SafeDownCast(prop)->GetProperty()->SetDiffuse(diffuse);
575                }
576            }
577        }
578    }
579
580    /**
581     * \brief Set the specular material coefficient and power
582     */
583    virtual void setSpecular(double coeff, double power)
584    {
585        if (getActor() != NULL) {
586            getActor()->GetProperty()->SetSpecular(coeff);
587            getActor()->GetProperty()->SetSpecularPower(power);
588        } else if (getVolume() != NULL) {
589            getVolume()->GetProperty()->SetSpecular(coeff);
590            getVolume()->GetProperty()->SetSpecularPower(power);
591        } else if (getAssembly() != NULL) {
592            vtkProp3DCollection *props = getAssembly()->GetParts();
593            vtkProp3D *prop;
594            props->InitTraversal();
595            while ((prop = props->GetNextProp3D()) != NULL) {
596                if (vtkActor::SafeDownCast(prop) != NULL) {
597                    vtkActor::SafeDownCast(prop)->GetProperty()->SetSpecular(coeff);
598                    vtkActor::SafeDownCast(prop)->GetProperty()->SetSpecularPower(power);
599                } else if (vtkVolume::SafeDownCast(prop) != NULL) {
600                    vtkVolume::SafeDownCast(prop)->GetProperty()->SetSpecular(coeff);
601                    vtkVolume::SafeDownCast(prop)->GetProperty()->SetSpecularPower(power);
602                }
603            }
604        }
605    }
606
607    /**
608     * \brief Set material properties (coefficients and specular power) of object
609     */
610    virtual void setMaterial(double ambient, double diffuse, double specular, double specPower)
611    {
612        if (getActor() != NULL) {
613            vtkProperty *property = getActor()->GetProperty();
614            property->SetAmbient(ambient);
615            property->SetDiffuse(diffuse);
616            property->SetSpecular(specular);
617            property->SetSpecularPower(specPower);
618        } else if (getImageActor() != NULL) {
619            vtkImageProperty *property = getImageActor()->GetProperty();
620            property->SetAmbient(ambient);
621            property->SetDiffuse(diffuse);
622        } else if (getVolume() != NULL) {
623            vtkVolumeProperty *property = getVolume()->GetProperty();
624            property->SetAmbient(ambient);
625            property->SetDiffuse(diffuse);
626            property->SetSpecular(specular);
627            property->SetSpecularPower(specPower);
628        } else if (getAssembly() != NULL) {
629            vtkProp3DCollection *props = getAssembly()->GetParts();
630            vtkProp3D *prop;
631            props->InitTraversal();
632            while ((prop = props->GetNextProp3D()) != NULL) {
633                if (vtkActor::SafeDownCast(prop) != NULL) {
634                    vtkProperty *property = vtkActor::SafeDownCast(prop)->GetProperty();
635                    property->SetAmbient(ambient);
636                    property->SetDiffuse(diffuse);
637                    property->SetSpecular(specular);
638                    property->SetSpecularPower(specPower);
639                } else if (vtkImageActor::SafeDownCast(prop) != NULL) {
640                    vtkImageProperty *property = vtkImageActor::SafeDownCast(prop)->GetProperty();
641                    property->SetAmbient(ambient);
642                    property->SetDiffuse(diffuse);
643                } else if (vtkVolume::SafeDownCast(prop) != NULL) {
644                    vtkVolumeProperty *property = vtkVolume::SafeDownCast(prop)->GetProperty();
645                    property->SetAmbient(ambient);
646                    property->SetDiffuse(diffuse);
647                    property->SetSpecular(specular);
648                    property->SetSpecularPower(specPower);
649                }
650            }
651        }
652    }
653
654    /**
655     * \brief Set the material color (sets ambient, diffuse, and specular)
656     */
657    virtual void setColor(float color[3])
658    {
659        for (int i = 0; i < 3; i++)
660            _color[i] = color[i];
661        if (getActor() != NULL) {
662            getActor()->GetProperty()->SetColor(color[0], color[1], color[2]);
663        } else if (getAssembly() != NULL) {
664            vtkProp3DCollection *props = getAssembly()->GetParts();
665            vtkProp3D *prop;
666            props->InitTraversal();
667            while ((prop = props->GetNextProp3D()) != NULL) {
668                if (vtkActor::SafeDownCast(prop) != NULL) {
669                    vtkActor::SafeDownCast(prop)->GetProperty()->SetColor(color[0], color[1], color[2]);
670                }
671            }
672        }
673    }
674
675    /**
676     * \brief Set the material ambient color
677     */
678    virtual void setAmbientColor(float color[3])
679    {
680        if (getActor() != NULL) {
681            getActor()->GetProperty()->SetAmbientColor(color[0], color[1], color[2]);
682        } else if (getAssembly() != NULL) {
683            vtkProp3DCollection *props = getAssembly()->GetParts();
684            vtkProp3D *prop;
685            props->InitTraversal();
686            while ((prop = props->GetNextProp3D()) != NULL) {
687                if (vtkActor::SafeDownCast(prop) != NULL) {
688                    vtkActor::SafeDownCast(prop)->GetProperty()->SetAmbientColor(color[0], color[1], color[2]);
689                }
690            }
691        }
692    }
693
694    /**
695     * \brief Set the material diffuse color
696     */
697    virtual void setDiffuseColor(float color[3])
698    {
699        if (getActor() != NULL) {
700            getActor()->GetProperty()->SetDiffuseColor(color[0], color[1], color[2]);
701        } else if (getAssembly() != NULL) {
702            vtkProp3DCollection *props = getAssembly()->GetParts();
703            vtkProp3D *prop;
704            props->InitTraversal();
705            while ((prop = props->GetNextProp3D()) != NULL) {
706                if (vtkActor::SafeDownCast(prop) != NULL) {
707                    vtkActor::SafeDownCast(prop)->GetProperty()->SetDiffuseColor(color[0], color[1], color[2]);
708                }
709            }
710        }
711    }
712
713    /**
714     * \brief Set the material specular color
715     */
716    virtual void setSpecularColor(float color[3])
717    {
718        if (getActor() != NULL) {
719            getActor()->GetProperty()->SetSpecularColor(color[0], color[1], color[2]);
720        } else if (getAssembly() != NULL) {
721            vtkProp3DCollection *props = getAssembly()->GetParts();
722            vtkProp3D *prop;
723            props->InitTraversal();
724            while ((prop = props->GetNextProp3D()) != NULL) {
725                if (vtkActor::SafeDownCast(prop) != NULL) {
726                    vtkActor::SafeDownCast(prop)->GetProperty()->SetSpecularColor(color[0], color[1], color[2]);
727                }
728            }
729        }
730    }
731
732    /**
733     * \brief Toggle lighting of the prop
734     */
735    virtual void setLighting(bool state)
736    {
737        _lighting = state;
738        if (getActor() != NULL) {
739            getActor()->GetProperty()->SetLighting((state ? 1 : 0));
740        } else if (getVolume() != NULL) {
741            getVolume()->GetProperty()->SetShade((state ? 1 : 0));
742         } else if (getAssembly() != NULL) {
743            vtkProp3DCollection *props = getAssembly()->GetParts();
744            vtkProp3D *prop;
745            props->InitTraversal();
746            while ((prop = props->GetNextProp3D()) != NULL) {
747                if (vtkActor::SafeDownCast(prop) != NULL) {
748                    vtkActor::SafeDownCast(prop)->GetProperty()->SetLighting((state ? 1 : 0));
749                } else if (vtkVolume::SafeDownCast(prop) != NULL) {
750                    vtkVolume::SafeDownCast(prop)->GetProperty()->SetShade((state ? 1 : 0));
751                }
752            }
753        }
754    }
755
756    /**
757     * \brief Set shading interpolation model of the prop
758     */
759    virtual void setShadingModel(ShadingModel state)
760    {
761        if (getActor() != NULL) {
762            getActor()->GetProperty()->SetInterpolation(state);
763        } else if (getAssembly() != NULL) {
764            vtkProp3DCollection *props = getAssembly()->GetParts();
765            vtkProp3D *prop;
766            props->InitTraversal();
767            while ((prop = props->GetNextProp3D()) != NULL) {
768                if (vtkActor::SafeDownCast(prop) != NULL) {
769                    vtkActor::SafeDownCast(prop)->GetProperty()->SetInterpolation(state);
770                }
771            }
772        }
773    }
774
775    /**
776     * \brief Toggle drawing of edges
777     */
778    virtual void setEdgeVisibility(bool state)
779    {
780        if (getActor() != NULL) {
781            getActor()->GetProperty()->SetEdgeVisibility((state ? 1 : 0));
782        } else if (getAssembly() != NULL) {
783            vtkProp3DCollection *props = getAssembly()->GetParts();
784            vtkProp3D *prop;
785            props->InitTraversal();
786            while ((prop = props->GetNextProp3D()) != NULL) {
787                if (vtkActor::SafeDownCast(prop) != NULL) {
788                    vtkActor::SafeDownCast(prop)->GetProperty()->SetEdgeVisibility((state ? 1 : 0));
789                }
790            }
791        }
792    }
793
794    /**
795     * \brief Set color of edges
796     */
797    virtual void setEdgeColor(float color[3])
798    {
799        for (int i = 0; i < 3; i++)
800            _edgeColor[i] = color[i];
801        if (getActor() != NULL) {
802            getActor()->GetProperty()->SetEdgeColor(color[0], color[1], color[2]);
803        } else if (getAssembly() != NULL) {
804            vtkProp3DCollection *props = getAssembly()->GetParts();
805            vtkProp3D *prop;
806            props->InitTraversal();
807            while ((prop = props->GetNextProp3D()) != NULL) {
808                if (vtkActor::SafeDownCast(prop) != NULL) {
809                    vtkActor::SafeDownCast(prop)->GetProperty()->SetEdgeColor(color[0], color[1], color[2]);
810                }
811            }
812        }
813    }
814
815    /**
816     * \brief Set pixel width of edges
817     *
818     * NOTE: May be a no-op if OpenGL implementation doesn't support wide lines
819     */
820    virtual void setEdgeWidth(float width)
821    {
822        _edgeWidth = width;
823        if (getActor() != NULL) {
824            getActor()->GetProperty()->SetLineWidth(width);
825        } else if (getAssembly() != NULL) {
826            vtkProp3DCollection *props = getAssembly()->GetParts();
827            vtkProp3D *prop;
828            props->InitTraversal();
829            while ((prop = props->GetNextProp3D()) != NULL) {
830                if (vtkActor::SafeDownCast(prop) != NULL) {
831                    vtkActor::SafeDownCast(prop)->GetProperty()->SetLineWidth(width);
832                }
833            }
834        }
835    }
836
837    /**
838     * \brief Set point size
839     *
840     * NOTE: May be a no-op if OpenGL implementation doesn't support wide points
841     */
842    virtual void setPointSize(float size)
843    {
844        _pointSize = size;
845        if (getActor() != NULL) {
846            getActor()->GetProperty()->SetPointSize(size);
847        } else if (getAssembly() != NULL) {
848            vtkProp3DCollection *props = getAssembly()->GetParts();
849            vtkProp3D *prop;
850            props->InitTraversal();
851            while ((prop = props->GetNextProp3D()) != NULL) {
852                if (vtkActor::SafeDownCast(prop) != NULL) {
853                    vtkActor::SafeDownCast(prop)->GetProperty()->SetPointSize(size);
854                }
855            }
856        }
857    }
858
859    /**
860     * \brief Toggle wireframe rendering of prop
861     */
862    virtual void setWireframe(bool state)
863    {
864        if (getActor() != NULL) {
865            if (state) {
866                getActor()->GetProperty()->SetRepresentationToWireframe();
867                getActor()->GetProperty()->LightingOff();
868            } else {
869                getActor()->GetProperty()->SetRepresentationToSurface();
870                setLighting(_lighting);
871            }
872        } else if (getAssembly() != NULL) {
873            vtkProp3DCollection *props = getAssembly()->GetParts();
874            vtkProp3D *prop;
875            props->InitTraversal();
876            while ((prop = props->GetNextProp3D()) != NULL) {
877                if (vtkActor::SafeDownCast(prop) != NULL) {
878                    if (state) {
879                        vtkActor::SafeDownCast(prop)->GetProperty()->SetRepresentationToWireframe();
880                        vtkActor::SafeDownCast(prop)->GetProperty()->LightingOff();
881                    } else {
882                        vtkActor::SafeDownCast(prop)->GetProperty()->SetRepresentationToSurface();
883                        vtkActor::SafeDownCast(prop)->GetProperty()->SetLighting((_lighting ? 1 : 0));
884                    }
885                }
886            }
887        }
888    }
889
890    /**
891     * \brief Toggle culling of selected CullFace
892     */
893    virtual void setCulling(bool state)
894    {
895        _faceCulling = state;
896        if (state && _opacity < 1.0)
897            return;
898        if (getActor() != NULL) {
899            setCulling(getActor()->GetProperty(), state);
900        } else if (getAssembly() != NULL) {
901            vtkProp3DCollection *props = getAssembly()->GetParts();
902            vtkProp3D *prop;
903            props->InitTraversal();
904            while ((prop = props->GetNextProp3D()) != NULL) {
905                if (vtkActor::SafeDownCast(prop) != NULL) {
906                    setCulling(vtkActor::SafeDownCast(prop)->GetProperty(), state);
907                }
908            }
909        }
910    }
911
912    /**
913     * \brief Specify which face(s) to cull when culling is enabled
914     */
915    virtual void setCullFace(CullFace cull)
916    {
917        _cullFace = cull;
918        setCulling(_faceCulling);
919    }
920
921    /**
922     * \brief Subclasses need to implement setting clipping planes in their mappers
923     */
924    virtual void setClippingPlanes(vtkPlaneCollection *planes) = 0;
925
926protected:
927    /**
928     * \brief Create and initialize a VTK Prop to render the object
929     */
930    virtual void initProp()
931    {
932        if (_prop == NULL) {
933            _prop = vtkSmartPointer<vtkActor>::New();
934            vtkProperty *property = getActor()->GetProperty();
935            property->SetColor(_color[0], _color[1], _color[2]);
936            property->SetEdgeColor(_edgeColor[0], _edgeColor[1], _edgeColor[2]);
937            property->SetLineWidth(_edgeWidth);
938            property->SetPointSize(_pointSize);
939            property->EdgeVisibilityOff();
940            if (_dataSet != NULL)
941                _opacity = _dataSet->getOpacity();
942            property->SetOpacity(_opacity);
943            property->SetAmbient(.2);
944            if (!_lighting)
945                property->LightingOff();
946            if (_faceCulling && _opacity == 1.0) {
947                setCulling(property, true);
948            }
949            if (_dataSet != NULL)
950                setVisibility(_dataSet->getVisibility());
951        }
952    }
953
954    /**
955     * \brief Subclasses implement this to create the VTK pipeline
956     * on a state change (e.g. new DataSet)
957     */
958    virtual void update() = 0;
959
960    /**
961     * \brief Convenience method to set culling state on a vtkProperty
962     *
963     * Note: Does not change the culling state flag of this GraphicsObject
964     */
965    virtual void setCulling(vtkProperty *property, bool state)
966    {
967        switch (_cullFace) {
968        case CULL_FRONT:
969            property->SetFrontfaceCulling((state ? 1 : 0));
970            property->BackfaceCullingOff();
971            break;
972        case CULL_BACK:
973            property->SetBackfaceCulling((state ? 1 : 0));
974            property->FrontfaceCullingOff();
975            break;
976        case CULL_FRONT_AND_BACK:
977            property->SetBackfaceCulling((state ? 1 : 0));
978            property->SetFrontfaceCulling((state ? 1 : 0));
979            break;
980        }
981    }
982
983    DataSet *_dataSet;
984    double _dataRange[2];
985    double _unscaledBounds[6];
986    double _opacity;
987    float _color[3];
988    float _edgeColor[3];
989    float _edgeWidth;
990    float _pointSize;
991    bool _lighting;
992    CullFace _cullFace;
993    bool _faceCulling;
994
995    vtkSmartPointer<vtkProp> _prop;
996};
997
998}
999
1000#endif
Note: See TracBrowser for help on using the repository browser.