source: vtkvis/tags/1.7.2/GraphicsObject.h @ 4832

Last change on this file since 4832 was 4783, checked in by ldelgass, 9 years ago

Merge some changes from trunk, including 2 new (currently unused) commands for
the image (slice) object

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