/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 2011, Purdue Research Foundation * * Author: Leif Delgass */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "RpPseudoColor.h" #include "Trace.h" #define MESH_POINT_CLOUDS using namespace Rappture::VtkVis; PseudoColor::PseudoColor() : VtkGraphicsObject(), _colorMode(COLOR_BY_SCALAR), _colorMap(NULL) { } PseudoColor::~PseudoColor() { #ifdef WANT_TRACE if (_dataSet != NULL) TRACE("Deleting PseudoColor for %s", _dataSet->getName().c_str()); else TRACE("Deleting PseudoColor with NULL DataSet"); #endif } void PseudoColor::setDataSet(DataSet *dataSet, bool useCumulative, double scalarRange[2], double vectorMagnitudeRange[2], double vectorComponentRange[3][2]) { if (_dataSet != dataSet) { _dataSet = dataSet; if (useCumulative) { _dataRange[0] = scalarRange[0]; _dataRange[1] = scalarRange[1]; _vectorMagnitudeRange[0] = vectorMagnitudeRange[0]; _vectorMagnitudeRange[1] = vectorMagnitudeRange[1]; for (int i = 0; i < 3; i++) { _vectorComponentRange[i][0] = vectorComponentRange[i][0]; _vectorComponentRange[i][1] = vectorComponentRange[i][1]; } } else { _dataSet->getScalarRange(_dataRange); _dataSet->getVectorRange(_vectorMagnitudeRange); for (int i = 0; i < 3; i++) { _dataSet->getVectorRange(_vectorComponentRange[i], i); } } update(); } } /** * \brief Internal method to set up pipeline after a state change */ void PseudoColor::update() { if (_dataSet == NULL) return; vtkDataSet *ds = _dataSet->getVtkDataSet(); // Mapper, actor to render color-mapped data set if (_dsMapper == NULL) { _dsMapper = vtkSmartPointer::New(); // Map scalars through lookup table regardless of type _dsMapper->SetColorModeToMapScalars(); //_dsMapper->InterpolateScalarsBeforeMappingOn(); } vtkPolyData *pd = vtkPolyData::SafeDownCast(ds); if (pd) { // DataSet is a vtkPolyData if (pd->GetNumberOfLines() == 0 && pd->GetNumberOfPolys() == 0 && pd->GetNumberOfStrips() == 0) { // DataSet is a point cloud DataSet::PrincipalPlane plane; double offset; if (_dataSet->is2D(&plane, &offset)) { #ifdef MESH_POINT_CLOUDS vtkSmartPointer mesher = vtkSmartPointer::New(); if (plane == DataSet::PLANE_ZY) { vtkSmartPointer trans = vtkSmartPointer::New(); trans->RotateWXYZ(90, 0, 1, 0); if (offset != 0.0) { trans->Translate(-offset, 0, 0); } mesher->SetTransform(trans); } else if (plane == DataSet::PLANE_XZ) { vtkSmartPointer trans = vtkSmartPointer::New(); trans->RotateWXYZ(-90, 1, 0, 0); if (offset != 0.0) { trans->Translate(0, -offset, 0); } mesher->SetTransform(trans); } else if (offset != 0.0) { // XY with Z offset vtkSmartPointer trans = vtkSmartPointer::New(); trans->Translate(0, 0, -offset); mesher->SetTransform(trans); } mesher->SetInput(pd); _dsMapper->SetInputConnection(mesher->GetOutputPort()); #else vtkSmartPointer splatter = vtkSmartPointer::New(); vtkSmartPointer slicer = vtkSmartPointer::New(); splatter->SetInput(pd); int dims[3]; splatter->GetSampleDimensions(dims); TRACE("Sample dims: %d %d %d", dims[0], dims[1], dims[2]); if (plane == DataSet::PLANE_ZY) { dims[0] = 3; slicer->SetVOI(1, 1, 0, dims[1]-1, 0, dims[1]-1); } else if (plane == DataSet::PLANE_XZ) { dims[1] = 3; slicer->SetVOI(0, dims[0]-1, 1, 1, 0, dims[2]-1); } else { dims[2] = 3; slicer->SetVOI(0, dims[0]-1, 0, dims[1]-1, 1, 1); } splatter->SetSampleDimensions(dims); double bounds[6]; splatter->Update(); splatter->GetModelBounds(bounds); TRACE("Model bounds: %g %g %g %g %g %g", bounds[0], bounds[1], bounds[2], bounds[3], bounds[4], bounds[5]); slicer->SetInputConnection(splatter->GetOutputPort()); slicer->SetSampleRate(1, 1, 1); vtkSmartPointer gf = vtkSmartPointer::New(); gf->UseStripsOn(); gf->SetInputConnection(slicer->GetOutputPort()); _dsMapper->SetInputConnection(gf->GetOutputPort()); #endif } else { vtkSmartPointer mesher = vtkSmartPointer::New(); mesher->SetInput(pd); vtkSmartPointer gf = vtkSmartPointer::New(); gf->SetInputConnection(mesher->GetOutputPort()); _dsMapper->SetInputConnection(gf->GetOutputPort()); } } else { // DataSet is a vtkPolyData with lines and/or polygons _dsMapper->SetInput(ds); } } else { TRACE("Generating surface for data set"); // DataSet is NOT a vtkPolyData vtkSmartPointer gf = vtkSmartPointer::New(); gf->SetInput(ds); _dsMapper->SetInputConnection(gf->GetOutputPort()); } if (_lut == NULL) { setColorMap(ColorMap::getDefault()); } setColorMode(_colorMode); initProp(); getActor()->SetMapper(_dsMapper); _dsMapper->Update(); } void PseudoColor::updateRanges(bool useCumulative, double scalarRange[2], double vectorMagnitudeRange[2], double vectorComponentRange[3][2]) { if (useCumulative) { _dataRange[0] = scalarRange[0]; _dataRange[1] = scalarRange[1]; _vectorMagnitudeRange[0] = vectorMagnitudeRange[0]; _vectorMagnitudeRange[1] = vectorMagnitudeRange[1]; for (int i = 0; i < 3; i++) { _vectorComponentRange[i][0] = vectorComponentRange[i][0]; _vectorComponentRange[i][1] = vectorComponentRange[i][1]; } } else if (_dataSet != NULL) { _dataSet->getScalarRange(_dataRange); _dataSet->getVectorRange(_vectorMagnitudeRange); for (int i = 0; i < 3; i++) { _dataSet->getVectorRange(_vectorComponentRange[i], i); } } // Need to update color map ranges and/or active vector field setColorMode(_colorMode); } void PseudoColor::setColorMode(ColorMode mode) { _colorMode = mode; if (_dataSet == NULL || _dsMapper == NULL) return; vtkDataSet *ds = _dataSet->getVtkDataSet(); switch (mode) { case COLOR_BY_SCALAR: { _dsMapper->ScalarVisibilityOn(); _dsMapper->SetScalarModeToDefault(); if (_lut != NULL) { _lut->SetRange(_dataRange); } } break; case COLOR_BY_VECTOR_MAGNITUDE: { _dsMapper->ScalarVisibilityOn(); _dsMapper->SetScalarModeToUsePointFieldData(); if (ds->GetPointData() != NULL && ds->GetPointData()->GetVectors() != NULL) { _dsMapper->SelectColorArray(ds->GetPointData()->GetVectors()->GetName()); } if (_lut != NULL) { _lut->SetRange(_vectorMagnitudeRange); _lut->SetVectorModeToMagnitude(); } } break; case COLOR_BY_VECTOR_X: _dsMapper->ScalarVisibilityOn(); _dsMapper->SetScalarModeToUsePointFieldData(); if (ds->GetPointData() != NULL && ds->GetPointData()->GetVectors() != NULL) { _dsMapper->SelectColorArray(ds->GetPointData()->GetVectors()->GetName()); } if (_lut != NULL) { _lut->SetRange(_vectorComponentRange[0]); _lut->SetVectorModeToComponent(); _lut->SetVectorComponent(0); } break; case COLOR_BY_VECTOR_Y: _dsMapper->ScalarVisibilityOn(); _dsMapper->SetScalarModeToUsePointFieldData(); if (ds->GetPointData() != NULL && ds->GetPointData()->GetVectors() != NULL) { _dsMapper->SelectColorArray(ds->GetPointData()->GetVectors()->GetName()); } if (_lut != NULL) { _lut->SetRange(_vectorComponentRange[1]); _lut->SetVectorModeToComponent(); _lut->SetVectorComponent(1); } break; case COLOR_BY_VECTOR_Z: _dsMapper->ScalarVisibilityOn(); _dsMapper->SetScalarModeToUsePointFieldData(); if (ds->GetPointData() != NULL && ds->GetPointData()->GetVectors() != NULL) { _dsMapper->SelectColorArray(ds->GetPointData()->GetVectors()->GetName()); } if (_lut != NULL) { _lut->SetRange(_vectorComponentRange[2]); _lut->SetVectorModeToComponent(); _lut->SetVectorComponent(2); } break; case COLOR_CONSTANT: default: _dsMapper->ScalarVisibilityOff(); break; } } /** * \brief Called when the color map has been edited */ void PseudoColor::updateColorMap() { setColorMap(_colorMap); } /** * \brief Associate a colormap lookup table with the DataSet */ void PseudoColor::setColorMap(ColorMap *cmap) { if (cmap == NULL) return; _colorMap = cmap; if (_lut == NULL) { _lut = vtkSmartPointer::New(); if (_dsMapper != NULL) { _dsMapper->UseLookupTableScalarRangeOn(); _dsMapper->SetLookupTable(_lut); } } _lut->DeepCopy(cmap->getLookupTable()); switch (_colorMode) { case COLOR_CONSTANT: case COLOR_BY_SCALAR: _lut->SetRange(_dataRange); break; case COLOR_BY_VECTOR_MAGNITUDE: _lut->SetVectorModeToMagnitude(); _lut->SetRange(_vectorMagnitudeRange); break; case COLOR_BY_VECTOR_X: _lut->SetVectorModeToComponent(); _lut->SetVectorComponent(0); _lut->SetRange(_vectorComponentRange[0]); break; case COLOR_BY_VECTOR_Y: _lut->SetVectorModeToComponent(); _lut->SetVectorComponent(1); _lut->SetRange(_vectorComponentRange[1]); break; case COLOR_BY_VECTOR_Z: _lut->SetVectorModeToComponent(); _lut->SetVectorComponent(2); _lut->SetRange(_vectorComponentRange[2]); break; default: break; } } /** * \brief Set a group of world coordinate planes to clip rendering * * Passing NULL for planes will remove all cliping planes */ void PseudoColor::setClippingPlanes(vtkPlaneCollection *planes) { if (_dsMapper != NULL) { _dsMapper->SetClippingPlanes(planes); } }