/*========================================================================= Program: Visualization Toolkit Module: vtkPolyDataMapper2D.cxx Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ #include "vtkPolyDataMapper2D.h" #include "vtkAbstractArray.h" #include "vtkColorSeries.h" #include "vtkCoordinate.h" #include "vtkDataArray.h" #include "vtkExecutive.h" #include "vtkInformation.h" #include "vtkLookupTable.h" #include "vtkObjectFactory.h" #include "vtkPolyData.h" #include "vtkVariantArray.h" //------------------------------------------------------------------------------ // Return nullptr if no override is supplied. vtkObjectFactoryNewMacro(vtkPolyDataMapper2D); //------------------------------------------------------------------------------ vtkCxxSetObjectMacro(vtkPolyDataMapper2D, TransformCoordinate, vtkCoordinate); //------------------------------------------------------------------------------ vtkPolyDataMapper2D::vtkPolyDataMapper2D() { this->Colors = nullptr; this->LookupTable = nullptr; this->ScalarVisibility = 1; this->ScalarRange[0] = 0.0; this->ScalarRange[1] = 1.0; this->UseLookupTableScalarRange = 0; this->ColorMode = VTK_COLOR_MODE_DEFAULT; this->ScalarMode = VTK_SCALAR_MODE_DEFAULT; this->TransformCoordinate = nullptr; this->TransformCoordinateUseDouble = false; strcpy(this->ArrayName, ""); this->ArrayId = -1; this->ArrayComponent = 0; this->ArrayAccessMode = VTK_GET_ARRAY_BY_ID; } //------------------------------------------------------------------------------ void vtkPolyDataMapper2D::ShallowCopy(vtkAbstractMapper* mapper) { vtkPolyDataMapper2D* m = vtkPolyDataMapper2D::SafeDownCast(mapper); if (m != nullptr) { this->SetLookupTable(m->GetLookupTable()); this->SetScalarVisibility(m->GetScalarVisibility()); this->SetScalarRange(m->GetScalarRange()); this->SetColorMode(m->GetColorMode()); this->SetScalarMode(m->GetScalarMode()); this->SetUseLookupTableScalarRange(m->GetUseLookupTableScalarRange()); this->ColorByArrayComponent(m->GetArrayName(), m->GetArrayComponent()); this->ColorByArrayComponent(m->GetArrayId(), m->GetArrayComponent()); this->SetTransformCoordinate(m->GetTransformCoordinate()); } // Now do superclass this->vtkMapper2D::ShallowCopy(mapper); } //------------------------------------------------------------------------------ vtkPolyDataMapper2D::~vtkPolyDataMapper2D() { if (this->TransformCoordinate) { this->TransformCoordinate->UnRegister(this); } if (this->LookupTable) { this->LookupTable->UnRegister(this); } if (this->Colors != nullptr) { this->Colors->UnRegister(this); } } //------------------------------------------------------------------------------ void vtkPolyDataMapper2D::SetInputData(vtkPolyData* input) { this->SetInputDataInternal(0, input); } //------------------------------------------------------------------------------ // Specify the input data or filter. vtkPolyData* vtkPolyDataMapper2D::GetInput() { if (this->GetNumberOfInputConnections(0) < 1) { return nullptr; } return vtkPolyData::SafeDownCast(this->GetExecutive()->GetInputData(0, 0)); } //------------------------------------------------------------------------------ // Overload standard modified time function. If lookup table is modified, // then this object is modified as well. vtkMTimeType vtkPolyDataMapper2D::GetMTime() { vtkMTimeType mTime = this->MTime; vtkMTimeType lutMTime; if (this->LookupTable != nullptr) { lutMTime = this->LookupTable->GetMTime(); mTime = (lutMTime > mTime ? lutMTime : mTime); } return mTime; } //------------------------------------------------------------------------------ // A side effect of this is that this->Colors is also set // to the return value vtkUnsignedCharArray* vtkPolyDataMapper2D::MapScalars(double alpha) { // Since we are not supporting the texture color option in this mapper, // the cell flag does nothing. int cellFlag = 0; // Get rid of old colors if (this->Colors) { this->Colors->UnRegister(this); this->Colors = nullptr; } // map scalars if necessary if (this->ScalarVisibility) { vtkAbstractArray* scalars = vtkAbstractMapper::GetAbstractScalars(this->GetInput(), this->ScalarMode, this->ArrayAccessMode, this->ArrayId, this->ArrayName, cellFlag); // This is for a legacy feature: selection of the array component to color by // from the mapper. It is now in the lookuptable. When this feature // is removed, we can remove this condition. if (scalars == nullptr || scalars->GetNumberOfComponents() <= this->ArrayComponent) { this->ArrayComponent = 0; } if (scalars) { vtkDataArray* dataArray = vtkArrayDownCast(scalars); if (dataArray && dataArray->GetLookupTable()) { this->SetLookupTable(dataArray->GetLookupTable()); } else { // make sure we have a lookup table if (this->LookupTable == nullptr) { this->CreateDefaultLookupTable(); } this->LookupTable->Build(); } if (!this->UseLookupTableScalarRange) { this->LookupTable->SetRange(this->ScalarRange); } this->LookupTable->SetAlpha(alpha); // Map Scalar constructs a array and returns it. // Not having "New" or "Make" in the name breaks VTK conventions but, ... this->Colors = this->LookupTable->MapScalars(scalars, this->ColorMode, this->ArrayComponent); this->Colors->Register(this); this->Colors->Delete(); } } return this->Colors; } //------------------------------------------------------------------------------ void vtkPolyDataMapper2D::ColorByArrayComponent(int arrayNum, int component) { if (this->ArrayId == arrayNum && component == this->ArrayComponent && this->ArrayAccessMode == VTK_GET_ARRAY_BY_ID) { return; } this->Modified(); this->ArrayId = arrayNum; this->ArrayComponent = component; this->ArrayAccessMode = VTK_GET_ARRAY_BY_ID; } //------------------------------------------------------------------------------ void vtkPolyDataMapper2D::ColorByArrayComponent(const char* arrayName, int component) { if (strcmp(this->ArrayName, arrayName) == 0 && component == this->ArrayComponent && this->ArrayAccessMode == VTK_GET_ARRAY_BY_ID) { return; } this->Modified(); strcpy(this->ArrayName, arrayName); this->ArrayComponent = component; this->ArrayAccessMode = VTK_GET_ARRAY_BY_NAME; } //------------------------------------------------------------------------------ // Specify a lookup table for the mapper to use. void vtkPolyDataMapper2D::SetLookupTable(vtkScalarsToColors* lut) { if (this->LookupTable != lut) { if (lut) { lut->Register(this); } if (this->LookupTable) { this->LookupTable->UnRegister(this); } this->LookupTable = lut; this->Modified(); } } //------------------------------------------------------------------------------ vtkScalarsToColors* vtkPolyDataMapper2D::GetLookupTable() { if (this->LookupTable == nullptr) { this->CreateDefaultLookupTable(); } return this->LookupTable; } //------------------------------------------------------------------------------ void vtkPolyDataMapper2D::CreateDefaultLookupTable() { if (this->LookupTable) { this->LookupTable->UnRegister(this); } vtkLookupTable* table = vtkLookupTable::New(); this->LookupTable = table; this->LookupTable->Register(this); this->LookupTable->Delete(); int cellFlag = 0; // not used vtkAbstractArray* abstractArray = vtkAbstractMapper::GetAbstractScalars(this->GetInput(), this->ScalarMode, this->ArrayAccessMode, this->ArrayId, this->ArrayName, cellFlag); vtkDataArray* dataArray = vtkArrayDownCast(abstractArray); if (abstractArray && !dataArray) { // Use indexed lookup for non-numeric arrays this->LookupTable->IndexedLookupOn(); // Get prominent values from array and set them up as annotations in the color map. vtkVariantArray* prominentValues = vtkVariantArray::New(); abstractArray->GetProminentComponentValues(0, prominentValues); vtkIdType numProminentValues = prominentValues->GetNumberOfValues(); table->SetNumberOfTableValues(numProminentValues); for (vtkIdType i = 0; i < numProminentValues; ++i) { vtkVariant& variant = prominentValues->GetValue(i); this->LookupTable->SetAnnotation(variant, variant.ToString()); } prominentValues->Delete(); // Set colors for annotations vtkColorSeries* colorSeries = vtkColorSeries::New(); colorSeries->SetColorScheme(vtkColorSeries::BREWER_QUALITATIVE_PAIRED); colorSeries->BuildLookupTable(table, vtkColorSeries::CATEGORICAL); colorSeries->Delete(); } } //------------------------------------------------------------------------------ // Return the method of coloring scalar data. const char* vtkPolyDataMapper2D::GetColorModeAsString() { return (this->ColorMode == VTK_COLOR_MODE_MAP_SCALARS) ? "MapScalars" : "Default"; } //------------------------------------------------------------------------------ void vtkPolyDataMapper2D::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os, indent); if (this->LookupTable) { os << indent << "Lookup Table:\n"; this->LookupTable->PrintSelf(os, indent.GetNextIndent()); } else { os << indent << "Lookup Table: (none)\n"; } os << indent << "Scalar Visibility: " << (this->ScalarVisibility ? "On\n" : "Off\n"); os << indent << "Scalar Mode: "; switch (this->ScalarMode) { case VTK_SCALAR_MODE_DEFAULT: os << "Default" << endl; break; case VTK_SCALAR_MODE_USE_POINT_DATA: os << "Use point data" << endl; break; case VTK_SCALAR_MODE_USE_CELL_DATA: os << "Use cell data" << endl; break; case VTK_SCALAR_MODE_USE_POINT_FIELD_DATA: os << "Use point field data" << endl; break; case VTK_SCALAR_MODE_USE_CELL_FIELD_DATA: os << "Use cell field data" << endl; break; } double* range = this->GetScalarRange(); os << indent << "Scalar Range: (" << range[0] << ", " << range[1] << ")\n"; os << indent << "UseLookupTableScalarRange: " << this->UseLookupTableScalarRange << "\n"; os << indent << "Color Mode: " << this->GetColorModeAsString() << endl; if (this->TransformCoordinate) { os << indent << "Transform Coordinate: " << this->TransformCoordinate << "\n"; this->TransformCoordinate->PrintSelf(os, indent.GetNextIndent()); } else { os << indent << "No Transform Coordinate\n"; } os << indent << "Transform Coordinate use double: " << (this->TransformCoordinateUseDouble ? "True\n" : "False\n") << "\n"; } //------------------------------------------------------------------------------ void vtkPolyDataMapper2D::SetColorModeToDefault() { this->SetColorMode(VTK_COLOR_MODE_DEFAULT); } //------------------------------------------------------------------------------ void vtkPolyDataMapper2D::SetColorModeToMapScalars() { this->SetColorMode(VTK_COLOR_MODE_MAP_SCALARS); } //------------------------------------------------------------------------------ void vtkPolyDataMapper2D::SetColorModeToDirectScalars() { this->SetColorMode(VTK_COLOR_MODE_DIRECT_SCALARS); } //------------------------------------------------------------------------------ int vtkPolyDataMapper2D::FillInputPortInformation(int vtkNotUsed(port), vtkInformation* info) { info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkPolyData"); return 1; }