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

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

Improvements to 3D shapes in vtkvis. Add preliminary, experimental grouping.

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