1 // Copyright (C) 2010-2023 CEA, EDF
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "vtkTableTo3D.h"
22 #include <vtkContourFilter.h>
23 #include <vtkDoubleArray.h>
24 #include <vtkInformation.h>
25 #include <vtkObjectFactory.h>
26 #include <vtkPointData.h>
27 #include <vtkPoints.h>
28 #include <vtkPolyData.h>
29 #include <vtkSmartPointer.h>
30 #include <vtkStructuredGrid.h>
31 #include <vtkStructuredGridGeometryFilter.h>
33 #include <vtkVariantArray.h>
34 #include <vtkWarpScalar.h>
36 vtkStandardNewMacro(vtkTableTo3D);
38 vtkTableTo3D::vtkTableTo3D()
40 this->ScaleFactor = 1.0;
41 this->UseOptimusScale = true;
42 this->PresentationType = TABLETO3D_SURFACE;
43 this->NumberOfContours = 32;
46 vtkTableTo3D::~vtkTableTo3D() {}
48 int vtkTableTo3D::FillInputPortInformation(int vtkNotUsed(port), vtkInformation* info)
50 info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkTable");
54 int vtkTableTo3D::RequestData(vtkInformation* vtkNotUsed(request),
55 vtkInformationVector** inputVector, vtkInformationVector* outputVector)
57 vtkTable* input = vtkTable::GetData(inputVector[0], 0);
58 vtkPolyData* output = vtkPolyData::GetData(outputVector, 0);
60 if (input->GetNumberOfRows() == 0 || input->GetNumberOfColumns() < 2)
65 vtkIdType xSize = input->GetNumberOfRows();
66 vtkIdType ySize = input->GetNumberOfColumns() - 1;
67 vtkIdType nbPoints = xSize * ySize;
69 vtkDataArray* xAxis = vtkDataArray::SafeDownCast(input->GetColumn(0));
72 vtkErrorMacro("The first column is not numeric.");
76 double xRange = xAxis->GetTuple1(xSize - 1) - xAxis->GetTuple1(0);
77 double yDelta = xRange / ySize;
79 vtkSmartPointer<vtkDoubleArray> yAxis = vtkSmartPointer<vtkDoubleArray>::New();
80 yAxis->SetNumberOfValues(ySize);
81 for (vtkIdType i = 0; i < ySize; i++)
83 yAxis->SetValue(i, i * yDelta);
86 vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
87 points->SetNumberOfPoints(nbPoints);
89 vtkSmartPointer<vtkIntArray> pointsIdMapper = vtkSmartPointer<vtkIntArray>::New();
90 pointsIdMapper->SetName("POINTS_ID_MAPPER");
91 pointsIdMapper->SetNumberOfComponents(2);
92 pointsIdMapper->SetNumberOfTuples(nbPoints);
93 int* pointsIdMapperPtr = pointsIdMapper->GetPointer(0);
95 for (vtkIdType i = 0, pntId = 0; i < ySize; i++)
97 for (vtkIdType j = 0; j < xSize; j++, pntId++)
99 points->SetPoint(pntId, xAxis->GetTuple1(j), yAxis->GetValue(i), 0.0);
101 *pointsIdMapperPtr++ = pntId;
102 *pointsIdMapperPtr++ = 0;
106 vtkSmartPointer<vtkDoubleArray> scalars = vtkSmartPointer<vtkDoubleArray>::New();
107 scalars->SetNumberOfComponents(1);
108 scalars->SetNumberOfTuples(nbPoints);
109 double* scalarsPtr = scalars->GetPointer(0);
110 for (vtkIdType i = 0; i < ySize; i++)
112 vtkDataArray* col = vtkDataArray::SafeDownCast(input->GetColumn(i + 1));
116 vtkErrorMacro("Column " << i << "is not numeric.");
120 for (vtkIdType j = 0; j < xSize; j++)
122 double value = col->GetTuple1(j);
123 *scalarsPtr++ = value;
127 vtkSmartPointer<vtkStructuredGrid> structuredGrid = vtkSmartPointer<vtkStructuredGrid>::New();
128 structuredGrid->SetPoints(points);
130 structuredGrid->SetDimensions(xSize, ySize, 1);
132 // structuredGrid->GetPointData()->AddArray(pointsIdMapper);
133 if (input->GetInformation()->Has(vtkDataObject::FIELD_NAME()))
135 scalars->SetName(input->GetInformation()->Get(vtkDataObject::FIELD_NAME()));
139 scalars->SetName("Table");
141 structuredGrid->GetPointData()->SetScalars(scalars);
143 vtkSmartPointer<vtkStructuredGridGeometryFilter> geomFilter =
144 vtkSmartPointer<vtkStructuredGridGeometryFilter>::New();
145 geomFilter->SetInputData(structuredGrid);
146 geomFilter->Update();
148 vtkSmartPointer<vtkWarpScalar> warpScalar = vtkSmartPointer<vtkWarpScalar>::New();
150 double scaleFactor = this->ScaleFactor;
151 if (this->UseOptimusScale)
154 geomFilter->GetOutput()->GetScalarRange(range);
155 double length = geomFilter->GetOutput()->GetLength();
158 scaleFactor = length / range[1] * 0.3;
166 if (this->PresentationType == TABLETO3D_SURFACE)
168 warpScalar->SetInputConnection(geomFilter->GetOutputPort(0));
169 warpScalar->SetScaleFactor(scaleFactor);
173 vtkSmartPointer<vtkContourFilter> contourFilter = vtkSmartPointer<vtkContourFilter>::New();
174 contourFilter->SetInputConnection(geomFilter->GetOutputPort(0));
175 contourFilter->GenerateValues(
176 this->NumberOfContours, geomFilter->GetOutput()->GetScalarRange());
177 warpScalar->SetInputConnection(contourFilter->GetOutputPort(0));
178 warpScalar->SetScaleFactor(scaleFactor);
181 warpScalar->Update();
182 output->ShallowCopy(warpScalar->GetPolyDataOutput());
187 //----------------------------------------------------------------------------
188 void vtkTableTo3D::PrintSelf(ostream& os, vtkIndent indent)
190 this->Superclass::PrintSelf(os, indent);
192 os << indent << "ScaleFactor: " << this->ScaleFactor << endl;
193 os << indent << "UseOptimusScale: " << (this->UseOptimusScale ? "true" : "false") << endl;
194 os << indent << "PresentationType: "
195 << ((this->PresentationType == TABLETO3D_SURFACE) ? "Surface" : "Contour") << endl;
196 os << indent << "NumberOfContours: " << this->NumberOfContours << endl;