From 521898a2b5969bdb930ed8d4bc2fdc9631473383 Mon Sep 17 00:00:00 2001 From: Nicolas Vuaille <nicolas.vuaille@kitware.com> Date: Tue, 3 Apr 2018 14:25:56 +0200 Subject: [PATCH] Molecule to polydata conversion * introduce vtkMoleculeToLinesFilter ** Create polydata with atom == point, bond == line cell. Copy data. * Fix AtomBall and BondStick conversion: ** set array name for bond orders and atomic numbers ** fix allocated size --- Domains/Chemistry/CMakeLists.txt | 1 + Domains/Chemistry/Testing/Cxx/CMakeLists.txt | 1 + .../Testing/Cxx/TestMoleculeToLines.cxx | 62 +++++++++++++++++++ .../Chemistry/vtkMoleculeToAtomBallFilter.cxx | 4 +- .../vtkMoleculeToBondStickFilter.cxx | 4 +- .../Chemistry/vtkMoleculeToLinesFilter.cxx | 50 +++++++++++++++ Domains/Chemistry/vtkMoleculeToLinesFilter.h | 51 +++++++++++++++ 7 files changed, 171 insertions(+), 2 deletions(-) create mode 100644 Domains/Chemistry/Testing/Cxx/TestMoleculeToLines.cxx create mode 100644 Domains/Chemistry/vtkMoleculeToLinesFilter.cxx create mode 100644 Domains/Chemistry/vtkMoleculeToLinesFilter.h diff --git a/Domains/Chemistry/CMakeLists.txt b/Domains/Chemistry/CMakeLists.txt index 5370210eea0..d9cdfc4aaa6 100644 --- a/Domains/Chemistry/CMakeLists.txt +++ b/Domains/Chemistry/CMakeLists.txt @@ -7,6 +7,7 @@ set(Module_SRCS vtkMoleculeMapper.cxx vtkMoleculeToAtomBallFilter.cxx vtkMoleculeToBondStickFilter.cxx + vtkMoleculeToLinesFilter.cxx vtkMoleculeToPolyDataFilter.cxx vtkPeriodicTable.cxx vtkPointSetToMoleculeFilter.cxx diff --git a/Domains/Chemistry/Testing/Cxx/CMakeLists.txt b/Domains/Chemistry/Testing/Cxx/CMakeLists.txt index c0235cc6722..b78e99f1fe5 100644 --- a/Domains/Chemistry/Testing/Cxx/CMakeLists.txt +++ b/Domains/Chemistry/Testing/Cxx/CMakeLists.txt @@ -28,6 +28,7 @@ vtk_add_test_cxx(vtkDomainsChemistryCxxTests tests TestMoleculeIOLegacy.cxx TestMoleculeSelection.cxx,NO_VALID TestMoleculeMapperPropertyUpdate.cxx + TestMoleculeToLines.cxx,NO_VALID TestMultiCylinderOn.cxx TestMultiCylinderOff.cxx TestPeriodicTable.cxx,NO_VALID diff --git a/Domains/Chemistry/Testing/Cxx/TestMoleculeToLines.cxx b/Domains/Chemistry/Testing/Cxx/TestMoleculeToLines.cxx new file mode 100644 index 00000000000..cd0a7c82511 --- /dev/null +++ b/Domains/Chemistry/Testing/Cxx/TestMoleculeToLines.cxx @@ -0,0 +1,62 @@ +/*========================================================================= + + Program: Visualization Toolkit + Module: TestMoleculeToLines.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 "vtkTestUtilities.h" + +#include "vtkCMLMoleculeReader.h" +#include "vtkCellData.h" +#include "vtkDataSetAttributes.h" +#include "vtkMolecule.h" +#include "vtkMoleculeToLinesFilter.h" +#include "vtkNew.h" +#include "vtkPointData.h" +#include "vtkPolyData.h" + +#define CheckNumbers(name, first, second) \ + if (first != second) \ + { \ + cerr << "Error : wrong number of " << #name << ". Got " << first << " but expects " << second \ + << endl; \ + return EXIT_FAILURE; \ + } + +int TestMoleculeToLines(int argc, char* argv[]) +{ + char* fileName = vtkTestUtilities::ExpandDataFileName(argc, argv, "Data/porphyrin.cml"); + + // read molecule from cml file + vtkNew<vtkCMLMoleculeReader> reader; + reader->SetFileName(fileName); + reader->Update(); + delete[] fileName; + vtkMolecule* molecule = reader->GetOutput(); + + // convert + vtkNew<vtkMoleculeToLinesFilter> converter; + converter->SetInputConnection(reader->GetOutputPort()); + converter->Update(); + vtkPolyData* poly = converter->GetOutput(); + + // check number of points, lines and associated data + CheckNumbers("points", poly->GetNumberOfPoints(), molecule->GetNumberOfAtoms()); + CheckNumbers("lines", poly->GetNumberOfLines(), molecule->GetNumberOfBonds()); + CheckNumbers("pointData", + poly->GetPointData()->GetNumberOfArrays(), + molecule->GetAtomData()->GetNumberOfArrays()); + CheckNumbers("cellData", + poly->GetCellData()->GetNumberOfArrays(), + molecule->GetBondData()->GetNumberOfArrays()); + return EXIT_SUCCESS; +} diff --git a/Domains/Chemistry/vtkMoleculeToAtomBallFilter.cxx b/Domains/Chemistry/vtkMoleculeToAtomBallFilter.cxx index 70a32b21ae6..cb99c2543e9 100644 --- a/Domains/Chemistry/vtkMoleculeToAtomBallFilter.cxx +++ b/Domains/Chemistry/vtkMoleculeToAtomBallFilter.cxx @@ -59,6 +59,7 @@ int vtkMoleculeToAtomBallFilter::RequestData( vtkCellArray *polys = vtkCellArray::New(); vtkPoints *points = vtkPoints::New(); vtkUnsignedShortArray *atomicNums = vtkUnsignedShortArray::New(); + atomicNums->SetName(input->GetAtomicNumberArrayName()); // Initialize a SphereSource vtkSphereSource *sphereSource = vtkSphereSource::New(); @@ -71,7 +72,8 @@ int vtkMoleculeToAtomBallFilter::RequestData( GetNumberOfPoints()); polys->Allocate(numAtoms * sphereSource->GetOutput()->GetPolys()-> GetNumberOfCells()); - atomicNums->Allocate(points->GetNumberOfPoints()); + atomicNums->Allocate(numAtoms * sphereSource->GetOutput()->GetPoints()-> + GetNumberOfPoints()); // Initialize some variables for later vtkIdType numCellPoints, *cellPoints; diff --git a/Domains/Chemistry/vtkMoleculeToBondStickFilter.cxx b/Domains/Chemistry/vtkMoleculeToBondStickFilter.cxx index e056c9b73cb..d510229de0a 100644 --- a/Domains/Chemistry/vtkMoleculeToBondStickFilter.cxx +++ b/Domains/Chemistry/vtkMoleculeToBondStickFilter.cxx @@ -52,6 +52,7 @@ int vtkMoleculeToBondStickFilter::RequestData( vtkCellArray *polys = vtkCellArray::New(); vtkPoints *points = vtkPoints::New(); vtkUnsignedShortArray *bondOrders = vtkUnsignedShortArray::New(); + bondOrders->SetName(input->GetBondOrdersArrayName()); // Initialize a CylinderSource vtkCylinderSource *cylSource = vtkCylinderSource::New(); @@ -64,7 +65,8 @@ int vtkMoleculeToBondStickFilter::RequestData( GetNumberOfPoints()); polys->Allocate(3 * numBonds * cylSource->GetOutput()->GetPolys()-> GetNumberOfCells()); - bondOrders->Allocate(points->GetNumberOfPoints()); + bondOrders->Allocate(3 * numBonds * cylSource->GetOutput()->GetPoints()-> + GetNumberOfPoints()); // Create a transform object to map the cylinder source to the bond vtkTransform *xform = vtkTransform::New(); diff --git a/Domains/Chemistry/vtkMoleculeToLinesFilter.cxx b/Domains/Chemistry/vtkMoleculeToLinesFilter.cxx new file mode 100644 index 00000000000..194f2fb4692 --- /dev/null +++ b/Domains/Chemistry/vtkMoleculeToLinesFilter.cxx @@ -0,0 +1,50 @@ +/*========================================================================= + + Program: Visualization Toolkit + Module: vtkMoleculeToLinesFilter.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 "vtkMoleculeToLinesFilter.h" + +#include "vtkCellArray.h" +#include "vtkCellData.h" +#include "vtkInformation.h" +#include "vtkMolecule.h" +#include "vtkPointData.h" + +vtkStandardNewMacro(vtkMoleculeToLinesFilter); + +//---------------------------------------------------------------------------- +int vtkMoleculeToLinesFilter::RequestData(vtkInformation*, + vtkInformationVector** inputVector, + vtkInformationVector* outputVector) +{ + vtkMolecule* input = vtkMolecule::SafeDownCast(vtkDataObject::GetData(inputVector[0])); + vtkPolyData* output = vtkPolyData::SafeDownCast(vtkDataObject::GetData(outputVector)); + + vtkNew<vtkCellArray> bonds; + // 2 point ids + 1 VTKCellType = 3 values per bonds + bonds->Allocate(3 * input->GetNumberOfBonds()); + + for (vtkIdType bondInd = 0; bondInd < input->GetNumberOfBonds(); ++bondInd) + { + vtkBond bond = input->GetBond(bondInd); + vtkIdType ids[2] = { bond.GetBeginAtomId(), bond.GetEndAtomId() }; + bonds->InsertNextCell(2, ids); + } + + output->SetPoints(input->GetAtomicPositionArray()); + output->SetLines(bonds); + output->GetPointData()->DeepCopy(input->GetAtomData()); + output->GetCellData()->DeepCopy(input->GetBondData()); + + return 1; +} diff --git a/Domains/Chemistry/vtkMoleculeToLinesFilter.h b/Domains/Chemistry/vtkMoleculeToLinesFilter.h new file mode 100644 index 00000000000..2f4a225966c --- /dev/null +++ b/Domains/Chemistry/vtkMoleculeToLinesFilter.h @@ -0,0 +1,51 @@ +/*========================================================================= + + Program: Visualization Toolkit + Module: vtkMoleculeToLinesFilter.h + + 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. + +=========================================================================*/ +/** + * @class vtkMoleculeToLinesFilter + * @brief Convert a molecule into a simple polydata with lines. + * + * vtkMoleculeToLinesFilter is a filter class that takes vtkMolecule as input and + * generates polydata on output. + * Conversion is done following this rules: + * - 1 atom == 1 point + * - 1 bond == 1 line (cell of type VTK_LINE) + * - atom data is copied as point data + * - bond data is copied as cell data + */ + +#ifndef vtkMoleculeToLinesFilter_h +#define vtkMoleculeToLinesFilter_h + +#include "vtkDomainsChemistryModule.h" // For export macro +#include "vtkMoleculeToPolyDataFilter.h" + +class VTKDOMAINSCHEMISTRY_EXPORT vtkMoleculeToLinesFilter : public vtkMoleculeToPolyDataFilter +{ +public: + static vtkMoleculeToLinesFilter* New(); + vtkTypeMacro(vtkMoleculeToLinesFilter, vtkMoleculeToPolyDataFilter); + +protected: + vtkMoleculeToLinesFilter() = default; + ~vtkMoleculeToLinesFilter() = default; + + int RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override; + +private: + vtkMoleculeToLinesFilter(const vtkMoleculeToLinesFilter&) = delete; + void operator=(const vtkMoleculeToLinesFilter&) = delete; +}; + +#endif -- GitLab