/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 2004-2012 HUBzero Foundation, LLC * * Author: Leif Delgass */ #ifndef VTKVIS_GRAPHICS_OBJECT_H #define VTKVIS_GRAPHICS_OBJECT_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "DataSet.h" #include "Trace.h" namespace VtkVis { class Renderer; /** * \brief Base class for graphics objects */ class GraphicsObject { public: enum CullFace { CULL_FRONT, CULL_BACK, CULL_FRONT_AND_BACK }; enum ShadingModel { SHADE_FLAT = VTK_FLAT, SHADE_GOURAUD = VTK_GOURAUD, SHADE_PHONG = VTK_PHONG }; GraphicsObject() : _dataSet(NULL), _opacity(1.0), _edgeWidth(1.0f), _pointSize(1.0f), _lighting(true), _cullFace(CULL_BACK), _faceCulling(false) { _dataRange[0] = 0; _dataRange[1] = 1; _color[0] = 1.0f; _color[1] = 1.0f; _color[2] = 1.0f; _edgeColor[0] = 0.0f; _edgeColor[1] = 0.0f; _edgeColor[2] = 0.0f; } virtual ~GraphicsObject() {} /** * \brief Return the name of the sublass of GraphicsObject */ virtual const char *getClassName() const = 0; /** * \brief Specify input DataSet and information on cumulative data ranges * * Default implementation calls update() and stores scalarRange to * _dataRange based on cumulative range settings * * \param[in] dataSet DataSet to use in rendering * \param[in] renderer Pointer to Renderer -- may be used to get * cumulative data ranges */ virtual void setDataSet(DataSet *dataSet, Renderer *renderer); /** * \brief Called when scalar or vector field changes (e.g. active field) or * cumulative ranges or settings change * * \param[in] renderer Pointer to Renderer -- may be used to get * cumulative data ranges */ virtual void updateRanges(Renderer *renderer); /** * \brief Return the DataSet this object renders */ inline DataSet *getDataSet() { return _dataSet; } /** * \brief Return the VTK prop object to render */ inline vtkProp *getProp() { return _prop; } /** * \brief Cast the vktProp to a vtkActor2D * * \return NULL or a vtkActor2D pointer */ inline vtkActor2D *getActor2D() { return vtkActor2D::SafeDownCast(_prop); } /** * \brief Cast the vktProp to a vtkProp3D * * \return NULL or a vtkProp3D pointer */ inline vtkProp3D *getProp3D() { return vtkProp3D::SafeDownCast(_prop); } /** * \brief Cast the vktProp to a vtkActor * * \return NULL or a vtkActor pointer */ inline vtkActor *getActor() { return vtkActor::SafeDownCast(_prop); } /** * \brief Cast the vktProp to a vtkImageActor * * \return NULL or a vtkImageActor pointer */ inline vtkImageActor *getImageActor() { return vtkImageActor::SafeDownCast(_prop); } /** * \brief Cast the vktProp to a vtkVolume * * \return NULL or a vtkVolume pointer */ inline vtkVolume *getVolume() { return vtkVolume::SafeDownCast(_prop); } /** * \brief Cast the vktProp to a vtkAssembly * * \return NULL or a vtkAssembly pointer */ inline vtkAssembly *getAssembly() { return vtkAssembly::SafeDownCast(_prop); } /** * \brief If the object has a 2D overlay prop, return it * * \return NULL or a vtkProp pointer */ virtual vtkProp *getOverlayProp() { return NULL; } /** * \brief Set an additional transform on the prop * * prop must be a vtkProp3D. The transform is * concatenated with the internal transform created * by setting the prop position, orientation and scale */ virtual void setTransform(vtkMatrix4x4 *matrix) { if (getProp3D() != NULL) { getProp3D()->SetUserMatrix(matrix); } } /** * \brief Set the prop center of rotation * * \param[in] origin The point about which the object rotates */ virtual void setOrigin(double origin[3]) { if (getProp3D() != NULL) { getProp3D()->SetOrigin(origin); } } /** * \brief Set the prop orientation with a quaternion * * \param[in] quat Quaternion with scalar part first */ virtual void setOrientation(double quat[4]) { if (getProp3D() != NULL) { double angle = vtkMath::DegreesFromRadians(2.0 * acos(quat[0])); double axis[3]; if (angle < 1.0e-6) { axis[0] = 1; axis[1] = 0; axis[2] = 0; } else { double denom = sqrt(1. - quat[0] * quat[0]); axis[0] = quat[1] / denom; axis[1] = quat[2] / denom; axis[2] = quat[3] / denom; } setOrientation(angle, axis); } } /** * \brief Set the prop orientation with a rotation about an axis * * \param[in] angle Angle in degrees * \param[in] axis Axis of rotation */ virtual void setOrientation(double angle, double axis[3]) { if (getProp3D() != NULL) { getProp3D()->SetOrientation(0, 0, 0); getProp3D()->RotateWXYZ(angle, axis[0], axis[1], axis[2]); } } /** * \brief Set the prop position * * \param[in] pos Position in world coordinates */ virtual void setPosition(double pos[3]) { if (getProp3D() != NULL) { getProp3D()->SetPosition(pos); } } /** * \brief Set 2D aspect ratio scaling * * \param aspect 0=no scaling, otherwise aspect * is horiz/vertical ratio */ virtual void setAspect(double aspect) { double scale[3]; scale[0] = scale[1] = scale[2] = 1.; if (aspect == 0.0) { setScale(scale); return; } if (_dataSet == NULL || _dataSet->getVtkDataSet() == NULL) { TRACE("Not setting aspect for object with no data set"); return; } PrincipalPlane plane; if (!_dataSet->is2D(&plane)) { TRACE("Not setting aspect for 3D object"); return; } double bounds[6]; vtkDataSet *ds = _dataSet->getVtkDataSet(); ds->GetBounds(bounds); double size[3]; size[0] = bounds[1] - bounds[0]; size[1] = bounds[3] - bounds[2]; size[2] = bounds[5] - bounds[4]; if (aspect == 1.0) { // Square switch (plane) { case PLANE_XY: { if (size[0] > size[1] && size[1] > 1.0e-6) { scale[1] = size[0] / size[1]; } else if (size[1] > size[0] && size[0] > 1.0e-6) { scale[0] = size[1] / size[0]; } } break; case PLANE_ZY: { if (size[1] > size[2] && size[2] > 1.0e-6) { scale[2] = size[1] / size[2]; } else if (size[2] > size[1] && size[1] > 1.0e-6) { scale[1] = size[2] / size[1]; } } break; case PLANE_XZ: { if (size[0] > size[2] && size[2] > 1.0e-6) { scale[2] = size[0] / size[2]; } else if (size[2] > size[0] && size[0] > 1.0e-6) { scale[0] = size[2] / size[0]; } } break; default: break; } } else { switch (plane) { case PLANE_XY: { if (aspect > 1.0) { if (size[0] > size[1]) { scale[1] = (size[0] / aspect) / size[1]; } else { scale[0] = (size[1] * aspect) / size[0]; } } else { if (size[1] > size[0]) { scale[0] = (size[1] * aspect) / size[0]; } else { scale[1] = (size[0] / aspect) / size[1]; } } } break; case PLANE_ZY: { if (aspect > 1.0) { if (size[2] > size[1]) { scale[1] = (size[2] / aspect) / size[1]; } else { scale[2] = (size[1] * aspect) / size[2]; } } else { if (size[1] > size[2]) { scale[2] = (size[1] * aspect) / size[2]; } else { scale[1] = (size[2] / aspect) / size[1]; } } } break; case PLANE_XZ: { if (aspect > 1.0) { if (size[0] > size[2]) { scale[2] = (size[0] / aspect) / size[2]; } else { scale[0] = (size[2] * aspect) / size[0]; } } else { if (size[2] > size[0]) { scale[0] = (size[2] * aspect) / size[0]; } else { scale[2] = (size[0] / aspect) / size[2]; } } } default: break; } } TRACE("obj %g,%g,%g", size[0], size[1], size[2]); TRACE("Setting scale to %g,%g,%g", scale[0], scale[1], scale[2]); setScale(scale); } /** * \brief Get the prop scaling * * \param[out] scale Scaling in x,y,z */ virtual void getScale(double scale[3]) { if (getProp3D() != NULL) { getProp3D()->GetScale(scale); } else { scale[0] = scale[1] = scale[2] = 1.0; } } /** * \brief Set the prop scaling * * \param[in] scale Scaling in x,y,z */ virtual void setScale(double scale[3]) { if (getProp3D() != NULL) { getProp3D()->SetScale(scale); } } /** * \brief Get the physical bounds of the prop * * If the prop is scaled, these bounds will be * scaled as well */ virtual double *getBounds() { if (getProp() != NULL) return getProp()->GetBounds(); else return NULL; } /** * \brief Get the data bounds of the prop * * If the prop is scaled, these bounds will NOT * be scaled, they will reflect the unscaled data * bounds. */ virtual double *getUnscaledBounds() { if (getProp3D() != NULL) { double scale[3]; getProp3D()->GetScale(scale); if (scale[0] == scale[1] && scale[1] == scale[2] && scale[0] == 1.0) { return getBounds(); } else if (getBounds() != NULL) { _unscaledBounds[0] = getBounds()[0] / scale[0]; _unscaledBounds[1] = getBounds()[1] / scale[0]; _unscaledBounds[2] = getBounds()[2] / scale[1]; _unscaledBounds[3] = getBounds()[3] / scale[1]; _unscaledBounds[4] = getBounds()[4] / scale[2]; _unscaledBounds[5] = getBounds()[5] / scale[2]; return _unscaledBounds; } } return getBounds(); } /** * \brief Toggle visibility of the prop */ virtual void setVisibility(bool state) { if (_prop != NULL) _prop->SetVisibility((state ? 1 : 0)); } /** * \brief Get visibility state of the prop */ virtual bool getVisibility() { if (_prop != NULL && _prop->GetVisibility() != 0) { return true; } else { return false; } } /** * \brief Set the opacity of the object * * The prop must be a vtkActor or vtkAssembly */ virtual void setOpacity(double opacity) { _opacity = opacity; if (getActor() != NULL) { getActor()->GetProperty()->SetOpacity(opacity); if (_faceCulling && _opacity < 1.0) { setCulling(getActor()->GetProperty(), false); TRACE("Culling off"); } else if (_faceCulling && _opacity == 1.0) { setCulling(getActor()->GetProperty(), true); TRACE("Culling on"); } } else if (getAssembly() != NULL) { vtkProp3DCollection *props = getAssembly()->GetParts(); vtkProp3D *prop; props->InitTraversal(); while ((prop = props->GetNextProp3D()) != NULL) { if (vtkActor::SafeDownCast(prop) != NULL) { vtkActor::SafeDownCast(prop)->GetProperty()->SetOpacity(opacity); if (_faceCulling && _opacity < 1.0) { setCulling(vtkActor::SafeDownCast(prop)->GetProperty(), false); TRACE("Culling off"); } else if (_faceCulling && _opacity == 1.0) { setCulling(vtkActor::SafeDownCast(prop)->GetProperty(), true); TRACE("Culling on"); } } else if (vtkImageActor::SafeDownCast(prop) != NULL) { vtkImageActor::SafeDownCast(prop)->GetProperty()->SetOpacity(opacity); } } } else if (getImageActor() != NULL) { getImageActor()->GetProperty()->SetOpacity(_opacity); } } /** * \brief Get the opacity of the object */ inline double getOpacity() { return _opacity; } /** * \brief Set the ambient material coefficient */ virtual void setAmbient(double ambient) { if (getActor() != NULL) { getActor()->GetProperty()->SetAmbient(ambient); } else if (getImageActor() != NULL) { getImageActor()->GetProperty()->SetAmbient(ambient); } else if (getVolume() != NULL) { getVolume()->GetProperty()->SetAmbient(ambient); } else if (getAssembly() != NULL) { vtkProp3DCollection *props = getAssembly()->GetParts(); vtkProp3D *prop; props->InitTraversal(); while ((prop = props->GetNextProp3D()) != NULL) { if (vtkActor::SafeDownCast(prop) != NULL) { vtkActor::SafeDownCast(prop)->GetProperty()->SetAmbient(ambient); } else if (vtkImageActor::SafeDownCast(prop) != NULL) { vtkImageActor::SafeDownCast(prop)->GetProperty()->SetAmbient(ambient); } else if (vtkVolume::SafeDownCast(prop) != NULL) { vtkVolume::SafeDownCast(prop)->GetProperty()->SetAmbient(ambient); } } } } /** * \brief Set the diffuse material coefficient */ virtual void setDiffuse(double diffuse) { if (getActor() != NULL) { getActor()->GetProperty()->SetDiffuse(diffuse); } else if (getImageActor() != NULL) { getImageActor()->GetProperty()->SetDiffuse(diffuse); } else if (getVolume() != NULL) { getVolume()->GetProperty()->SetDiffuse(diffuse); } else if (getAssembly() != NULL) { vtkProp3DCollection *props = getAssembly()->GetParts(); vtkProp3D *prop; props->InitTraversal(); while ((prop = props->GetNextProp3D()) != NULL) { if (vtkActor::SafeDownCast(prop) != NULL) { vtkActor::SafeDownCast(prop)->GetProperty()->SetDiffuse(diffuse); } else if (vtkImageActor::SafeDownCast(prop) != NULL) { vtkImageActor::SafeDownCast(prop)->GetProperty()->SetDiffuse(diffuse); } else if (vtkVolume::SafeDownCast(prop) != NULL) { vtkVolume::SafeDownCast(prop)->GetProperty()->SetDiffuse(diffuse); } } } } /** * \brief Set the specular material coefficient and power */ virtual void setSpecular(double coeff, double power) { if (getActor() != NULL) { getActor()->GetProperty()->SetSpecular(coeff); getActor()->GetProperty()->SetSpecularPower(power); } else if (getVolume() != NULL) { getVolume()->GetProperty()->SetSpecular(coeff); getVolume()->GetProperty()->SetSpecularPower(power); } else if (getAssembly() != NULL) { vtkProp3DCollection *props = getAssembly()->GetParts(); vtkProp3D *prop; props->InitTraversal(); while ((prop = props->GetNextProp3D()) != NULL) { if (vtkActor::SafeDownCast(prop) != NULL) { vtkActor::SafeDownCast(prop)->GetProperty()->SetSpecular(coeff); vtkActor::SafeDownCast(prop)->GetProperty()->SetSpecularPower(power); } else if (vtkVolume::SafeDownCast(prop) != NULL) { vtkVolume::SafeDownCast(prop)->GetProperty()->SetSpecular(coeff); vtkVolume::SafeDownCast(prop)->GetProperty()->SetSpecularPower(power); } } } } /** * \brief Set material properties (coefficients and specular power) of object */ virtual void setMaterial(double ambient, double diffuse, double specular, double specPower) { if (getActor() != NULL) { vtkProperty *property = getActor()->GetProperty(); property->SetAmbient(ambient); property->SetDiffuse(diffuse); property->SetSpecular(specular); property->SetSpecularPower(specPower); } else if (getImageActor() != NULL) { vtkImageProperty *property = getImageActor()->GetProperty(); property->SetAmbient(ambient); property->SetDiffuse(diffuse); } else if (getVolume() != NULL) { vtkVolumeProperty *property = getVolume()->GetProperty(); property->SetAmbient(ambient); property->SetDiffuse(diffuse); property->SetSpecular(specular); property->SetSpecularPower(specPower); } else if (getAssembly() != NULL) { vtkProp3DCollection *props = getAssembly()->GetParts(); vtkProp3D *prop; props->InitTraversal(); while ((prop = props->GetNextProp3D()) != NULL) { if (vtkActor::SafeDownCast(prop) != NULL) { vtkProperty *property = vtkActor::SafeDownCast(prop)->GetProperty(); property->SetAmbient(ambient); property->SetDiffuse(diffuse); property->SetSpecular(specular); property->SetSpecularPower(specPower); } else if (vtkImageActor::SafeDownCast(prop) != NULL) { vtkImageProperty *property = vtkImageActor::SafeDownCast(prop)->GetProperty(); property->SetAmbient(ambient); property->SetDiffuse(diffuse); } else if (vtkVolume::SafeDownCast(prop) != NULL) { vtkVolumeProperty *property = vtkVolume::SafeDownCast(prop)->GetProperty(); property->SetAmbient(ambient); property->SetDiffuse(diffuse); property->SetSpecular(specular); property->SetSpecularPower(specPower); } } } } /** * \brief Set the material color (sets ambient, diffuse, and specular) */ virtual void setColor(float color[3]) { for (int i = 0; i < 3; i++) _color[i] = color[i]; if (getActor() != NULL) { getActor()->GetProperty()->SetColor(color[0], color[1], color[2]); } else if (getAssembly() != NULL) { vtkProp3DCollection *props = getAssembly()->GetParts(); vtkProp3D *prop; props->InitTraversal(); while ((prop = props->GetNextProp3D()) != NULL) { if (vtkActor::SafeDownCast(prop) != NULL) { vtkActor::SafeDownCast(prop)->GetProperty()->SetColor(color[0], color[1], color[2]); } } } } /** * \brief Set the material ambient color */ virtual void setAmbientColor(float color[3]) { if (getActor() != NULL) { getActor()->GetProperty()->SetAmbientColor(color[0], color[1], color[2]); } else if (getAssembly() != NULL) { vtkProp3DCollection *props = getAssembly()->GetParts(); vtkProp3D *prop; props->InitTraversal(); while ((prop = props->GetNextProp3D()) != NULL) { if (vtkActor::SafeDownCast(prop) != NULL) { vtkActor::SafeDownCast(prop)->GetProperty()->SetAmbientColor(color[0], color[1], color[2]); } } } } /** * \brief Set the material diffuse color */ virtual void setDiffuseColor(float color[3]) { if (getActor() != NULL) { getActor()->GetProperty()->SetDiffuseColor(color[0], color[1], color[2]); } else if (getAssembly() != NULL) { vtkProp3DCollection *props = getAssembly()->GetParts(); vtkProp3D *prop; props->InitTraversal(); while ((prop = props->GetNextProp3D()) != NULL) { if (vtkActor::SafeDownCast(prop) != NULL) { vtkActor::SafeDownCast(prop)->GetProperty()->SetDiffuseColor(color[0], color[1], color[2]); } } } } /** * \brief Set the material specular color */ virtual void setSpecularColor(float color[3]) { if (getActor() != NULL) { getActor()->GetProperty()->SetSpecularColor(color[0], color[1], color[2]); } else if (getAssembly() != NULL) { vtkProp3DCollection *props = getAssembly()->GetParts(); vtkProp3D *prop; props->InitTraversal(); while ((prop = props->GetNextProp3D()) != NULL) { if (vtkActor::SafeDownCast(prop) != NULL) { vtkActor::SafeDownCast(prop)->GetProperty()->SetSpecularColor(color[0], color[1], color[2]); } } } } /** * \brief Toggle lighting of the prop */ virtual void setLighting(bool state) { _lighting = state; if (getActor() != NULL) { getActor()->GetProperty()->SetLighting((state ? 1 : 0)); } else if (getVolume() != NULL) { getVolume()->GetProperty()->SetShade((state ? 1 : 0)); } else if (getAssembly() != NULL) { vtkProp3DCollection *props = getAssembly()->GetParts(); vtkProp3D *prop; props->InitTraversal(); while ((prop = props->GetNextProp3D()) != NULL) { if (vtkActor::SafeDownCast(prop) != NULL) { vtkActor::SafeDownCast(prop)->GetProperty()->SetLighting((state ? 1 : 0)); } else if (vtkVolume::SafeDownCast(prop) != NULL) { vtkVolume::SafeDownCast(prop)->GetProperty()->SetShade((state ? 1 : 0)); } } } } /** * \brief Set shading interpolation model of the prop */ virtual void setShadingModel(ShadingModel state) { if (getActor() != NULL) { getActor()->GetProperty()->SetInterpolation(state); } else if (getAssembly() != NULL) { vtkProp3DCollection *props = getAssembly()->GetParts(); vtkProp3D *prop; props->InitTraversal(); while ((prop = props->GetNextProp3D()) != NULL) { if (vtkActor::SafeDownCast(prop) != NULL) { vtkActor::SafeDownCast(prop)->GetProperty()->SetInterpolation(state); } } } } /** * \brief Toggle drawing of edges */ virtual void setEdgeVisibility(bool state) { if (getActor() != NULL) { getActor()->GetProperty()->SetEdgeVisibility((state ? 1 : 0)); } else if (getAssembly() != NULL) { vtkProp3DCollection *props = getAssembly()->GetParts(); vtkProp3D *prop; props->InitTraversal(); while ((prop = props->GetNextProp3D()) != NULL) { if (vtkActor::SafeDownCast(prop) != NULL) { vtkActor::SafeDownCast(prop)->GetProperty()->SetEdgeVisibility((state ? 1 : 0)); } } } } /** * \brief Set color of edges */ virtual void setEdgeColor(float color[3]) { for (int i = 0; i < 3; i++) _edgeColor[i] = color[i]; if (getActor() != NULL) { getActor()->GetProperty()->SetEdgeColor(color[0], color[1], color[2]); } else if (getAssembly() != NULL) { vtkProp3DCollection *props = getAssembly()->GetParts(); vtkProp3D *prop; props->InitTraversal(); while ((prop = props->GetNextProp3D()) != NULL) { if (vtkActor::SafeDownCast(prop) != NULL) { vtkActor::SafeDownCast(prop)->GetProperty()->SetEdgeColor(color[0], color[1], color[2]); } } } } /** * \brief Set pixel width of edges * * NOTE: May be a no-op if OpenGL implementation doesn't support wide lines */ virtual void setEdgeWidth(float width) { _edgeWidth = width; if (getActor() != NULL) { getActor()->GetProperty()->SetLineWidth(width); } else if (getAssembly() != NULL) { vtkProp3DCollection *props = getAssembly()->GetParts(); vtkProp3D *prop; props->InitTraversal(); while ((prop = props->GetNextProp3D()) != NULL) { if (vtkActor::SafeDownCast(prop) != NULL) { vtkActor::SafeDownCast(prop)->GetProperty()->SetLineWidth(width); } } } } /** * \brief Set point size * * NOTE: May be a no-op if OpenGL implementation doesn't support wide points */ virtual void setPointSize(float size) { _pointSize = size; if (getActor() != NULL) { getActor()->GetProperty()->SetPointSize(size); } else if (getAssembly() != NULL) { vtkProp3DCollection *props = getAssembly()->GetParts(); vtkProp3D *prop; props->InitTraversal(); while ((prop = props->GetNextProp3D()) != NULL) { if (vtkActor::SafeDownCast(prop) != NULL) { vtkActor::SafeDownCast(prop)->GetProperty()->SetPointSize(size); } } } } /** * \brief Toggle wireframe rendering of prop */ virtual void setWireframe(bool state) { if (getActor() != NULL) { if (state) { getActor()->GetProperty()->SetRepresentationToWireframe(); getActor()->GetProperty()->LightingOff(); } else { getActor()->GetProperty()->SetRepresentationToSurface(); setLighting(_lighting); } } else if (getAssembly() != NULL) { vtkProp3DCollection *props = getAssembly()->GetParts(); vtkProp3D *prop; props->InitTraversal(); while ((prop = props->GetNextProp3D()) != NULL) { if (vtkActor::SafeDownCast(prop) != NULL) { if (state) { vtkActor::SafeDownCast(prop)->GetProperty()->SetRepresentationToWireframe(); vtkActor::SafeDownCast(prop)->GetProperty()->LightingOff(); } else { vtkActor::SafeDownCast(prop)->GetProperty()->SetRepresentationToSurface(); vtkActor::SafeDownCast(prop)->GetProperty()->SetLighting((_lighting ? 1 : 0)); } } } } } /** * \brief Toggle culling of selected CullFace */ virtual void setCulling(bool state) { _faceCulling = state; if (state && _opacity < 1.0) return; if (getActor() != NULL) { setCulling(getActor()->GetProperty(), state); } else if (getAssembly() != NULL) { vtkProp3DCollection *props = getAssembly()->GetParts(); vtkProp3D *prop; props->InitTraversal(); while ((prop = props->GetNextProp3D()) != NULL) { if (vtkActor::SafeDownCast(prop) != NULL) { setCulling(vtkActor::SafeDownCast(prop)->GetProperty(), state); } } } } /** * \brief Specify which face(s) to cull when culling is enabled */ virtual void setCullFace(CullFace cull) { _cullFace = cull; setCulling(_faceCulling); } /** * \brief Subclasses need to implement setting clipping planes in their mappers */ virtual void setClippingPlanes(vtkPlaneCollection *planes) = 0; protected: /** * \brief Create and initialize a VTK Prop to render the object */ virtual void initProp() { if (_prop == NULL) { _prop = vtkSmartPointer::New(); vtkProperty *property = getActor()->GetProperty(); property->SetColor(_color[0], _color[1], _color[2]); property->SetEdgeColor(_edgeColor[0], _edgeColor[1], _edgeColor[2]); property->SetLineWidth(_edgeWidth); property->SetPointSize(_pointSize); property->EdgeVisibilityOff(); if (_dataSet != NULL) _opacity = _dataSet->getOpacity(); property->SetOpacity(_opacity); property->SetAmbient(.2); if (!_lighting) property->LightingOff(); if (_faceCulling && _opacity == 1.0) { setCulling(property, true); } if (_dataSet != NULL) setVisibility(_dataSet->getVisibility()); } } /** * \brief Subclasses implement this to create the VTK pipeline * on a state change (e.g. new DataSet) */ virtual void update() = 0; /** * \brief Convenience method to set culling state on a vtkProperty * * Note: Does not change the culling state flag of this GraphicsObject */ virtual void setCulling(vtkProperty *property, bool state) { switch (_cullFace) { case CULL_FRONT: property->SetFrontfaceCulling((state ? 1 : 0)); property->BackfaceCullingOff(); break; case CULL_BACK: property->SetBackfaceCulling((state ? 1 : 0)); property->FrontfaceCullingOff(); break; case CULL_FRONT_AND_BACK: property->SetBackfaceCulling((state ? 1 : 0)); property->SetFrontfaceCulling((state ? 1 : 0)); break; } } DataSet *_dataSet; double _dataRange[2]; double _unscaledBounds[6]; double _opacity; float _color[3]; float _edgeColor[3]; float _edgeWidth; float _pointSize; bool _lighting; CullFace _cullFace; bool _faceCulling; vtkSmartPointer _prop; }; } #endif