source: branches/Rappture 1.2/packages/vizservers/vtkvis/RpVtkGraphicsObject.h @ 3208

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

Add generic aspect ratio scaling impl.

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