/*========================================================================= Program: Visualization Toolkit Module: vtkGDALRasterReader.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 "vtkPDALReader.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(__GNUC__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wshadow" #pragma GCC diagnostic ignored "-Wunused-parameter" #if __GNUC__ > 6 #pragma GCC diagnostic ignored "-Wnoexcept-type" #endif #endif #include #if defined(__GNUC__) #pragma GCC diagnostic pop #endif #include #include #include #include vtkStandardNewMacro(vtkPDALReader); //------------------------------------------------------------------------------ vtkPDALReader::vtkPDALReader() { this->FileName = nullptr; this->SetNumberOfInputPorts(0); this->SetNumberOfOutputPorts(1); } //------------------------------------------------------------------------------ vtkPDALReader::~vtkPDALReader() { delete[] this->FileName; } //------------------------------------------------------------------------------ int vtkPDALReader::RequestData(vtkInformation* vtkNotUsed(request), vtkInformationVector** vtkNotUsed(request), vtkInformationVector* outputVector) { try { // Get the info object vtkInformation* outInfo = outputVector->GetInformationObject(0); // Get the output vtkPolyData* output = vtkPolyData::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())); pdal::StageFactory factory; std::string driverName = pdal::StageFactory::inferReaderDriver(this->FileName); if (driverName.empty()) { vtkErrorMacro("Cannot infer the reader driver for " << this->FileName); return 0; } pdal::Option opt_filename("filename", this->FileName); pdal::Options opts; opts.add(opt_filename); pdal::Stage* reader = factory.createStage(driverName); if (!reader) { vtkErrorMacro("Cannot open file " << this->FileName); return 0; } reader->setOptions(opts); vtkNew pointsPolyData; this->ReadPointRecordData(*reader, pointsPolyData); // Convert points to verts in output polydata vtkNew vertexFilter; vertexFilter->SetInputData(pointsPolyData); vertexFilter->Update(); output->ShallowCopy(vertexFilter->GetOutput()); return VTK_OK; } catch (const std::exception& e) { vtkErrorMacro("exception: " << e.what()); } catch (...) { vtkErrorMacro("Unknown exception"); } return 0; } //------------------------------------------------------------------------------ void vtkPDALReader::ReadPointRecordData(pdal::Stage& reader, vtkPolyData* pointsPolyData) { vtkNew points; points->SetDataTypeToDouble(); pointsPolyData->SetPoints(points); pdal::PointTable table; reader.prepare(table); pdal::PointViewSet pointViewSet = reader.execute(table); pdal::PointViewPtr pointView = *pointViewSet.begin(); points->SetNumberOfPoints(pointView->size()); pdal::Dimension::IdList dims = pointView->dims(); std::vector doubleArray(dims.size(), nullptr); std::vector floatArray(dims.size(), nullptr); std::vector uInt8Array(dims.size(), nullptr); std::vector uInt16Array(dims.size(), nullptr); std::vector uInt32Array(dims.size(), nullptr); std::vector uInt64Array(dims.size(), nullptr); std::vector int8Array(dims.size(), nullptr); std::vector int16Array(dims.size(), nullptr); std::vector int32Array(dims.size(), nullptr); std::vector int64Array(dims.size(), nullptr); vtkTypeUInt16Array* colorArray = nullptr; // check if we have a color field, and create the required array bool hasColor = false, hasRed = false, hasGreen = false, hasBlue = false; for (size_t i = 0; i < dims.size(); ++i) { pdal::Dimension::Id dimensionId = dims[i]; switch (dimensionId) { case pdal::Dimension::Id::Red: hasRed = true; break; case pdal::Dimension::Id::Green: hasGreen = true; break; case pdal::Dimension::Id::Blue: hasBlue = true; break; default: continue; } } if (hasRed && hasGreen && hasBlue) { hasColor = true; vtkNew a; a->SetNumberOfComponents(3); a->SetNumberOfTuples(pointView->size()); a->SetName("Color"); pointsPolyData->GetPointData()->AddArray(a); colorArray = a; } // create arrays for fields for (size_t i = 0; i < dims.size(); ++i) { pdal::Dimension::Id dimensionId = dims[i]; if (dimensionId == pdal::Dimension::Id::X || dimensionId == pdal::Dimension::Id::Y || dimensionId == pdal::Dimension::Id::Z) { continue; } if (hasColor && (dimensionId == pdal::Dimension::Id::Red || dimensionId == pdal::Dimension::Id::Green || dimensionId == pdal::Dimension::Id::Blue)) { continue; } switch (pointView->dimType(dimensionId)) { case pdal::Dimension::Type::Double: { vtkNew a; a->SetName(pointView->dimName(dimensionId).c_str()); a->SetNumberOfTuples(pointView->size()); pointsPolyData->GetPointData()->AddArray(a); doubleArray[i] = a; break; } case pdal::Dimension::Type::Float: { vtkNew a; a->SetName(pointView->dimName(dimensionId).c_str()); a->SetNumberOfTuples(pointView->size()); pointsPolyData->GetPointData()->AddArray(a); floatArray[i] = a; break; } case pdal::Dimension::Type::Unsigned8: { vtkNew a; a->SetName(pointView->dimName(dimensionId).c_str()); a->SetNumberOfTuples(pointView->size()); pointsPolyData->GetPointData()->AddArray(a); uInt8Array[i] = a; break; } case pdal::Dimension::Type::Unsigned16: { vtkNew a; a->SetName(pointView->dimName(dimensionId).c_str()); a->SetNumberOfTuples(pointView->size()); pointsPolyData->GetPointData()->AddArray(a); uInt16Array[i] = a; break; } case pdal::Dimension::Type::Unsigned32: { vtkNew a; a->SetName(pointView->dimName(dimensionId).c_str()); a->SetNumberOfTuples(pointView->size()); pointsPolyData->GetPointData()->AddArray(a); uInt32Array[i] = a; break; } case pdal::Dimension::Type::Unsigned64: { vtkNew a; a->SetName(pointView->dimName(dimensionId).c_str()); a->SetNumberOfTuples(pointView->size()); pointsPolyData->GetPointData()->AddArray(a); uInt64Array[i] = a; break; } case pdal::Dimension::Type::Signed8: { vtkNew a; a->SetName(pointView->dimName(dimensionId).c_str()); a->SetNumberOfTuples(pointView->size()); pointsPolyData->GetPointData()->AddArray(a); int8Array[i] = a; break; } case pdal::Dimension::Type::Signed16: { vtkNew a; a->SetName(pointView->dimName(dimensionId).c_str()); a->SetNumberOfTuples(pointView->size()); pointsPolyData->GetPointData()->AddArray(a); int16Array[i] = a; break; } case pdal::Dimension::Type::Signed32: { vtkNew a; a->SetName(pointView->dimName(dimensionId).c_str()); a->SetNumberOfTuples(pointView->size()); pointsPolyData->GetPointData()->AddArray(a); int32Array[i] = a; break; } case pdal::Dimension::Type::Signed64: { vtkNew a; a->SetName(pointView->dimName(dimensionId).c_str()); a->SetNumberOfTuples(pointView->size()); pointsPolyData->GetPointData()->AddArray(a); int64Array[i] = a; break; } default: throw std::runtime_error("Invalid pdal::Dimension::Type"); } } for (pdal::PointId pointId = 0; pointId < pointView->size(); ++pointId) { double point[3] = { pointView->getFieldAs(pdal::Dimension::Id::X, pointId), pointView->getFieldAs(pdal::Dimension::Id::Y, pointId), pointView->getFieldAs(pdal::Dimension::Id::Z, pointId) }; points->SetPoint(pointId, point); if (hasColor) { uint16_t color[3] = { pointView->getFieldAs(pdal::Dimension::Id::Red, pointId), pointView->getFieldAs(pdal::Dimension::Id::Green, pointId), pointView->getFieldAs(pdal::Dimension::Id::Blue, pointId), }; colorArray->SetTypedTuple(pointId, color); } for (size_t i = 0; i < dims.size(); ++i) { pdal::Dimension::Id dimensionId = dims[i]; if (dimensionId == pdal::Dimension::Id::X || dimensionId == pdal::Dimension::Id::Y || dimensionId == pdal::Dimension::Id::Z) { continue; } if (hasColor && (dimensionId == pdal::Dimension::Id::Red || dimensionId == pdal::Dimension::Id::Green || dimensionId == pdal::Dimension::Id::Blue)) { continue; } switch (pointView->dimType(dimensionId)) { case pdal::Dimension::Type::Double: { vtkDoubleArray* a = doubleArray[i]; double value = pointView->getFieldAs(dimensionId, pointId); a->SetValue(pointId, value); break; } case pdal::Dimension::Type::Float: { vtkFloatArray* a = floatArray[i]; float value = pointView->getFieldAs(dimensionId, pointId); a->SetValue(pointId, value); break; } case pdal::Dimension::Type::Unsigned8: { vtkTypeUInt8Array* a = uInt8Array[i]; uint8_t value = pointView->getFieldAs(dimensionId, pointId); a->SetValue(pointId, value); break; } case pdal::Dimension::Type::Unsigned16: { vtkTypeUInt16Array* a = uInt16Array[i]; uint16_t value = pointView->getFieldAs(dimensionId, pointId); a->SetValue(pointId, value); break; } case pdal::Dimension::Type::Unsigned32: { vtkTypeUInt32Array* a = uInt32Array[i]; uint32_t value = pointView->getFieldAs(dimensionId, pointId); a->SetValue(pointId, value); break; } case pdal::Dimension::Type::Unsigned64: { vtkTypeUInt64Array* a = uInt64Array[i]; uint64_t value = pointView->getFieldAs(dimensionId, pointId); a->SetValue(pointId, value); break; } case pdal::Dimension::Type::Signed8: { vtkTypeInt8Array* a = int8Array[i]; int8_t value = pointView->getFieldAs(dimensionId, pointId); a->SetValue(pointId, value); break; } case pdal::Dimension::Type::Signed16: { vtkTypeInt16Array* a = int16Array[i]; int16_t value = pointView->getFieldAs(dimensionId, pointId); a->SetValue(pointId, value); break; } case pdal::Dimension::Type::Signed32: { vtkTypeInt32Array* a = int32Array[i]; int32_t value = pointView->getFieldAs(dimensionId, pointId); a->SetValue(pointId, value); break; } case pdal::Dimension::Type::Signed64: { vtkTypeInt64Array* a = int64Array[i]; int64_t value = pointView->getFieldAs(dimensionId, pointId); a->SetValue(pointId, value); break; } default: throw std::runtime_error("Invalid pdal::Dimension::Type"); } } } } //------------------------------------------------------------------------------ void vtkPDALReader::PrintSelf(ostream& os, vtkIndent indent) { Superclass::PrintSelf(os, indent); os << "vtkPDALReader" << std::endl; os << "Filename: " << this->FileName << std::endl; }