From 5b8c282e9fb10a5b775809cf43b339b7402a6a94 Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Thu, 27 Jul 2023 14:07:19 -0600 Subject: [PATCH] Continue transfer of Users' Guide text These changes complete the using part of the guide. --- CMake/VTKmExportHeaderTemplate.h.in | 6 +- CMake/doxyfile.in | 8 +- docs/users-guide/base-types.rst | 2 +- docs/users-guide/color-table-presets.rst | 21 + docs/users-guide/dataset.rst | 592 +++++++++ docs/users-guide/error-handling.rst | 114 ++ docs/users-guide/examples/CMakeLists.txt | 25 + .../examples/GuideExampleColorTables.cxx | 111 ++ .../examples/GuideExampleDataSetCreation.cxx | 652 ++++++++++ .../examples/GuideExampleErrorHandling.cxx | 176 +++ docs/users-guide/examples/GuideExampleIO.cxx | 161 +++ .../examples/GuideExampleInitialization.cxx | 211 +++ .../examples/GuideExampleProvidedFilters.cxx | 556 ++++++++ .../examples/GuideExampleRendering.cxx | 214 +++ .../GuideExampleRenderingInteractive.cxx | 392 ++++++ .../GuideExampleRuntimeDeviceTracker.cxx | 96 ++ .../examples/GuideExampleTimer.cxx | 61 + .../AlternateRendering-EdgeRendering.png | 3 + ...lternateRendering-GlyphRenderingArrows.png | 3 + ...AlternateRendering-GlyphRenderingCubes.png | 3 + ...ternateRendering-GlyphRenderingSpheres.png | 3 + .../users-guide/images/AlternateRendering.png | 3 + docs/users-guide/images/BasicRendering.png | 3 + docs/users-guide/images/CameraMovement.pdf | 3 + docs/users-guide/images/CameraMovement.png | 3 + .../images/CameraPositionOrientation.pdf | 3 + .../images/CameraPositionOrientation.png | 3 + docs/users-guide/images/CameraViewRange2D.pdf | 3 + docs/users-guide/images/CameraViewRange2D.png | 3 + docs/users-guide/images/CellConnections.png | 3 + .../images/CellConnectionsHexahedron.pdf | 3 + .../images/CellConnectionsHexahedron.png | 3 + .../images/CellConnectionsLine.pdf | 3 + .../images/CellConnectionsLine.png | 3 + .../images/CellConnectionsPolyLine.pdf | 3 + .../images/CellConnectionsPolyLine.png | 3 + .../images/CellConnectionsPolygon.pdf | 3 + .../images/CellConnectionsPolygon.png | 3 + .../images/CellConnectionsPyramid.pdf | 3 + .../images/CellConnectionsPyramid.png | 3 + .../images/CellConnectionsQuadrilateral.pdf | 3 + .../images/CellConnectionsQuadrilateral.png | 3 + .../images/CellConnectionsTetrahedron.pdf | 3 + .../images/CellConnectionsTetrahedron.png | 3 + .../images/CellConnectionsTriangle.pdf | 3 + .../images/CellConnectionsTriangle.png | 3 + .../images/CellConnectionsVertex.pdf | 3 + .../images/CellConnectionsVertex.png | 3 + .../images/CellConnectionsWedge.pdf | 3 + .../images/CellConnectionsWedge.png | 3 + docs/users-guide/images/CellConstituents.pdf | 3 + docs/users-guide/images/CellConstituents.png | 3 + .../images/ExplicitCellConnections.pdf | 3 + .../images/ExplicitCellConnections.png | 3 + docs/users-guide/images/ExtrudedCellSet.pdf | 3 + docs/users-guide/images/ExtrudedCellSet.png | 3 + docs/users-guide/images/ImplicitBox.png | 3 + docs/users-guide/images/ImplicitCylinder.png | 3 + docs/users-guide/images/ImplicitFrustum.png | 3 + docs/users-guide/images/ImplicitPlane.png | 3 + docs/users-guide/images/ImplicitSphere.png | 3 + docs/users-guide/images/StructuredCellSet.pdf | 3 + docs/users-guide/images/StructuredCellSet.png | 3 + .../color-tables/Black---Blue---White.png | 3 + .../color-tables/Black-Body-Radiation.png | 3 + .../color-tables/Blue---Green---Orange.png | 3 + .../images/color-tables/Blue-to-Orange.png | 3 + .../images/color-tables/Cold-and-Hot.png | 3 + .../color-tables/Cool-to-Warm-Extended.png | 3 + .../images/color-tables/Cool-to-Warm.png | 3 + .../images/color-tables/Default.png | 3 + .../images/color-tables/Gray-to-Red.png | 3 + .../users-guide/images/color-tables/Green.png | 3 + .../images/color-tables/Inferno.png | 3 + docs/users-guide/images/color-tables/Jet.png | 3 + .../images/color-tables/Plasma.png | 3 + .../color-tables/Rainbow-Desaturated.png | 3 + .../images/color-tables/Rainbow-Uniform.png | 3 + .../images/color-tables/Viridis.png | 3 + .../users-guide/images/color-tables/X-Ray.png | 3 + .../color-tables/Yellow---Gray---Blue.png | 3 + docs/users-guide/implicit-functions.rst | 167 +++ docs/users-guide/initialization.rst | 35 + docs/users-guide/io.rst | 143 ++ docs/users-guide/managing-devices.rst | 167 +++ docs/users-guide/part-using.rst | 11 + docs/users-guide/provided-filters.rst | 1150 +++++++++++++++++ docs/users-guide/quick-start.rst | 13 +- docs/users-guide/rendering.rst | 661 ++++++++++ docs/users-guide/running-filters.rst | 188 +++ docs/users-guide/timer.rst | 42 + docs/users-guide/version.rst | 67 + docs/users-guide/vtkm.module | 5 + vtkm/ImplicitFunction.h | 91 +- vtkm/cont/ArrayHandleRecombineVec.h | 2 + vtkm/cont/ArrayRangeComputeTemplate.h | 2 + vtkm/cont/CellSet.h | 18 + vtkm/cont/CellSetExplicit.h | 20 +- vtkm/cont/CellSetExtrude.h | 7 + vtkm/cont/CellSetPermutation.h | 33 +- vtkm/cont/CellSetSingleType.h | 44 +- vtkm/cont/CellSetStructured.h | 10 + vtkm/cont/ConvertNumComponentsToOffsets.h | 11 +- vtkm/cont/CoordinateSystem.h | 5 + vtkm/cont/DataSet.h | 23 + vtkm/cont/DataSetBuilderExplicit.h | 238 +++- vtkm/cont/DataSetBuilderRectilinear.h | 102 +- vtkm/cont/DataSetBuilderUniform.h | 63 +- vtkm/cont/DeviceAdapterTag.h | 36 +- vtkm/cont/Error.h | 6 +- vtkm/cont/Field.h | 56 + vtkm/cont/Initialize.h | 35 +- vtkm/cont/Logging.h | 2 + vtkm/cont/PartitionedDataSet.h | 61 +- vtkm/cont/RuntimeDeviceTracker.h | 56 +- vtkm/cont/Timer.h | 34 +- .../cont/cuda/internal/DeviceAdapterTagCuda.h | 7 + .../kokkos/internal/DeviceAdapterTagKokkos.h | 8 + .../openmp/internal/DeviceAdapterTagOpenMP.h | 8 + .../serial/internal/DeviceAdapterTagSerial.h | 7 + vtkm/cont/tbb/internal/DeviceAdapterTagTBB.h | 8 + vtkm/filter/Filter.h | 47 +- vtkm/filter/FilterField.h | 91 +- vtkm/filter/clean_grid/CleanGrid.h | 37 +- .../CellSetConnectivity.h | 11 +- .../connected_components/ImageConnectivity.h | 12 +- vtkm/filter/contour/AbstractContour.h | 72 +- vtkm/filter/contour/ClipWithField.h | 26 +- .../filter/contour/ClipWithImplicitFunction.h | 19 +- vtkm/filter/contour/Contour.h | 24 +- vtkm/filter/contour/Slice.h | 13 +- vtkm/filter/density_estimate/Histogram.h | 67 +- .../density_estimate/ParticleDensityBase.h | 39 +- .../ParticleDensityCloudInCell.h | 31 +- .../ParticleDensityNearestGridPoint.h | 31 +- vtkm/filter/density_estimate/Statistics.h | 46 +- vtkm/filter/entity_extraction/ExternalFaces.h | 37 +- .../entity_extraction/ExtractGeometry.h | 42 +- vtkm/filter/entity_extraction/ExtractPoints.h | 29 +- .../entity_extraction/ExtractStructured.h | 49 +- vtkm/filter/entity_extraction/Threshold.h | 110 +- .../UnitTestExtractStructuredFilter.cxx | 3 + vtkm/filter/field_conversion/CellAverage.h | 7 +- vtkm/filter/field_conversion/PointAverage.h | 6 + .../filter/field_transform/CompositeVectors.h | 15 +- .../CylindricalCoordinateTransform.h | 12 +- vtkm/filter/field_transform/FieldToColors.h | 65 +- vtkm/filter/field_transform/GenerateIds.h | 24 +- vtkm/filter/field_transform/LogValues.h | 53 +- vtkm/filter/field_transform/PointElevation.h | 40 +- vtkm/filter/field_transform/PointTransform.h | 77 +- .../SphericalCoordinateTransform.h | 10 + vtkm/filter/flow/FilterParticleAdvection.h | 22 +- .../FilterParticleAdvectionUnsteadyState.h | 10 + vtkm/filter/flow/LagrangianStructures.h | 47 + vtkm/filter/flow/Pathline.h | 13 +- vtkm/filter/flow/StreamSurface.h | 36 +- vtkm/filter/flow/Streamline.h | 13 +- .../geometry_refinement/ConvertToPointCloud.h | 5 +- vtkm/filter/geometry_refinement/Shrink.h | 15 +- .../geometry_refinement/SplitSharpEdges.h | 43 +- .../geometry_refinement/Tetrahedralize.h | 10 + vtkm/filter/geometry_refinement/Triangulate.h | 10 + vtkm/filter/geometry_refinement/Tube.h | 30 +- .../geometry_refinement/VertexClustering.h | 20 +- vtkm/filter/mesh_info/GhostCellClassify.h | 16 + vtkm/filter/multi_block/AmrArrays.h | 35 + vtkm/filter/resampling/HistSampling.cxx | 20 +- vtkm/filter/resampling/HistSampling.h | 58 +- vtkm/filter/resampling/Probe.h | 32 +- .../contourtree_augmented/DataSetMesh.h | 7 +- .../worklet/contourtree_augmented/Types.h | 7 +- .../ComputeDistributedContourTreeFunctor.h | 7 +- .../HierarchicalHyperSweeper.h | 1 - ...CopyNewSupernodesSetSuperchildrenWorklet.h | 2 +- vtkm/filter/vector_analysis/CrossProduct.h | 78 +- vtkm/filter/vector_analysis/DotProduct.h | 89 +- vtkm/filter/vector_analysis/Gradient.h | 73 +- vtkm/filter/vector_analysis/SurfaceNormals.h | 85 +- vtkm/filter/vector_analysis/VectorMagnitude.h | 8 + vtkm/filter/zfp/ZFPCompressor1D.h | 10 +- vtkm/filter/zfp/ZFPCompressor2D.h | 10 +- vtkm/filter/zfp/ZFPCompressor3D.h | 10 +- vtkm/filter/zfp/ZFPDecompressor1D.h | 11 +- vtkm/filter/zfp/ZFPDecompressor2D.h | 12 +- vtkm/filter/zfp/ZFPDecompressor3D.h | 12 +- vtkm/internal/ExportMacros.h | 2 +- vtkm/io/ErrorIO.h | 3 + vtkm/io/ImageReaderBase.h | 6 +- vtkm/io/ImageReaderPNG.h | 12 +- vtkm/io/ImageReaderPNM.h | 18 +- vtkm/io/ImageWriterBase.h | 11 +- vtkm/io/ImageWriterPNG.h | 12 +- vtkm/io/ImageWriterPNM.h | 15 +- vtkm/io/VTKDataSetReader.h | 7 + vtkm/io/VTKDataSetReaderBase.h | 3 +- vtkm/io/VTKDataSetWriter.h | 17 +- vtkm/rendering/Actor.h | 20 + vtkm/rendering/Camera.h | 148 ++- vtkm/rendering/Canvas.h | 29 +- vtkm/rendering/CanvasRayTracer.h | 3 + vtkm/rendering/Color.h | 19 +- vtkm/rendering/Mapper.h | 4 + vtkm/rendering/MapperCylinder.h | 2 +- vtkm/rendering/MapperGlyphBase.cxx | 16 +- vtkm/rendering/MapperGlyphBase.h | 20 +- vtkm/rendering/MapperGlyphScalar.cxx | 8 +- vtkm/rendering/MapperGlyphVector.cxx | 8 +- vtkm/rendering/MapperPoint.cxx | 96 +- vtkm/rendering/MapperPoint.h | 70 +- vtkm/rendering/MapperQuad.h | 3 +- vtkm/rendering/MapperRayTracer.h | 4 + vtkm/rendering/MapperVolume.h | 6 + vtkm/rendering/MapperWireframer.h | 10 + vtkm/rendering/Scene.h | 7 + vtkm/rendering/View.h | 20 +- vtkm/rendering/View1D.h | 5 + vtkm/rendering/View2D.h | 3 + vtkm/rendering/View3D.h | 1 + vtkm/rendering/testlib/RenderTest.cxx | 2 +- 220 files changed, 8896 insertions(+), 948 deletions(-) create mode 100644 docs/users-guide/color-table-presets.rst create mode 100644 docs/users-guide/dataset.rst create mode 100644 docs/users-guide/error-handling.rst create mode 100644 docs/users-guide/examples/GuideExampleColorTables.cxx create mode 100644 docs/users-guide/examples/GuideExampleDataSetCreation.cxx create mode 100644 docs/users-guide/examples/GuideExampleErrorHandling.cxx create mode 100644 docs/users-guide/examples/GuideExampleIO.cxx create mode 100644 docs/users-guide/examples/GuideExampleInitialization.cxx create mode 100644 docs/users-guide/examples/GuideExampleProvidedFilters.cxx create mode 100644 docs/users-guide/examples/GuideExampleRendering.cxx create mode 100644 docs/users-guide/examples/GuideExampleRenderingInteractive.cxx create mode 100644 docs/users-guide/examples/GuideExampleRuntimeDeviceTracker.cxx create mode 100644 docs/users-guide/examples/GuideExampleTimer.cxx create mode 100644 docs/users-guide/images/AlternateRendering-EdgeRendering.png create mode 100644 docs/users-guide/images/AlternateRendering-GlyphRenderingArrows.png create mode 100644 docs/users-guide/images/AlternateRendering-GlyphRenderingCubes.png create mode 100644 docs/users-guide/images/AlternateRendering-GlyphRenderingSpheres.png create mode 100644 docs/users-guide/images/AlternateRendering.png create mode 100644 docs/users-guide/images/BasicRendering.png create mode 100644 docs/users-guide/images/CameraMovement.pdf create mode 100644 docs/users-guide/images/CameraMovement.png create mode 100644 docs/users-guide/images/CameraPositionOrientation.pdf create mode 100644 docs/users-guide/images/CameraPositionOrientation.png create mode 100644 docs/users-guide/images/CameraViewRange2D.pdf create mode 100644 docs/users-guide/images/CameraViewRange2D.png create mode 100644 docs/users-guide/images/CellConnections.png create mode 100644 docs/users-guide/images/CellConnectionsHexahedron.pdf create mode 100644 docs/users-guide/images/CellConnectionsHexahedron.png create mode 100644 docs/users-guide/images/CellConnectionsLine.pdf create mode 100644 docs/users-guide/images/CellConnectionsLine.png create mode 100644 docs/users-guide/images/CellConnectionsPolyLine.pdf create mode 100644 docs/users-guide/images/CellConnectionsPolyLine.png create mode 100644 docs/users-guide/images/CellConnectionsPolygon.pdf create mode 100644 docs/users-guide/images/CellConnectionsPolygon.png create mode 100644 docs/users-guide/images/CellConnectionsPyramid.pdf create mode 100644 docs/users-guide/images/CellConnectionsPyramid.png create mode 100644 docs/users-guide/images/CellConnectionsQuadrilateral.pdf create mode 100644 docs/users-guide/images/CellConnectionsQuadrilateral.png create mode 100644 docs/users-guide/images/CellConnectionsTetrahedron.pdf create mode 100644 docs/users-guide/images/CellConnectionsTetrahedron.png create mode 100644 docs/users-guide/images/CellConnectionsTriangle.pdf create mode 100644 docs/users-guide/images/CellConnectionsTriangle.png create mode 100644 docs/users-guide/images/CellConnectionsVertex.pdf create mode 100644 docs/users-guide/images/CellConnectionsVertex.png create mode 100644 docs/users-guide/images/CellConnectionsWedge.pdf create mode 100644 docs/users-guide/images/CellConnectionsWedge.png create mode 100644 docs/users-guide/images/CellConstituents.pdf create mode 100644 docs/users-guide/images/CellConstituents.png create mode 100644 docs/users-guide/images/ExplicitCellConnections.pdf create mode 100644 docs/users-guide/images/ExplicitCellConnections.png create mode 100644 docs/users-guide/images/ExtrudedCellSet.pdf create mode 100644 docs/users-guide/images/ExtrudedCellSet.png create mode 100644 docs/users-guide/images/ImplicitBox.png create mode 100644 docs/users-guide/images/ImplicitCylinder.png create mode 100644 docs/users-guide/images/ImplicitFrustum.png create mode 100644 docs/users-guide/images/ImplicitPlane.png create mode 100644 docs/users-guide/images/ImplicitSphere.png create mode 100644 docs/users-guide/images/StructuredCellSet.pdf create mode 100644 docs/users-guide/images/StructuredCellSet.png create mode 100644 docs/users-guide/images/color-tables/Black---Blue---White.png create mode 100644 docs/users-guide/images/color-tables/Black-Body-Radiation.png create mode 100644 docs/users-guide/images/color-tables/Blue---Green---Orange.png create mode 100644 docs/users-guide/images/color-tables/Blue-to-Orange.png create mode 100644 docs/users-guide/images/color-tables/Cold-and-Hot.png create mode 100644 docs/users-guide/images/color-tables/Cool-to-Warm-Extended.png create mode 100644 docs/users-guide/images/color-tables/Cool-to-Warm.png create mode 100644 docs/users-guide/images/color-tables/Default.png create mode 100644 docs/users-guide/images/color-tables/Gray-to-Red.png create mode 100644 docs/users-guide/images/color-tables/Green.png create mode 100644 docs/users-guide/images/color-tables/Inferno.png create mode 100644 docs/users-guide/images/color-tables/Jet.png create mode 100644 docs/users-guide/images/color-tables/Plasma.png create mode 100644 docs/users-guide/images/color-tables/Rainbow-Desaturated.png create mode 100644 docs/users-guide/images/color-tables/Rainbow-Uniform.png create mode 100644 docs/users-guide/images/color-tables/Viridis.png create mode 100644 docs/users-guide/images/color-tables/X-Ray.png create mode 100644 docs/users-guide/images/color-tables/Yellow---Gray---Blue.png create mode 100644 docs/users-guide/implicit-functions.rst create mode 100644 docs/users-guide/initialization.rst create mode 100644 docs/users-guide/io.rst create mode 100644 docs/users-guide/managing-devices.rst create mode 100644 docs/users-guide/provided-filters.rst create mode 100644 docs/users-guide/rendering.rst create mode 100644 docs/users-guide/running-filters.rst create mode 100644 docs/users-guide/timer.rst create mode 100644 docs/users-guide/version.rst diff --git a/CMake/VTKmExportHeaderTemplate.h.in b/CMake/VTKmExportHeaderTemplate.h.in index f560012f8..191c35951 100644 --- a/CMake/VTKmExportHeaderTemplate.h.in +++ b/CMake/VTKmExportHeaderTemplate.h.in @@ -10,7 +10,11 @@ #ifndef @EXPORT_MACRO_NAME@_EXPORT_H #define @EXPORT_MACRO_NAME@_EXPORT_H -#if defined(_MSC_VER) +#if defined(VTKM_DOXYGEN_ONLY) +# define @EXPORT_MACRO_NAME@_EXPORT_DEFINE +# define @EXPORT_MACRO_NAME@_IMPORT_DEFINE +# define @EXPORT_MACRO_NAME@_NO_EXPORT_DEFINE +#elif defined(_MSC_VER) # if @EXPORT_IS_BUILT_STATIC@ /* This is a static component and has no need for exports elf based static libraries are able to have hidden/default visibility diff --git a/CMake/doxyfile.in b/CMake/doxyfile.in index ff74e0387..646947b52 100644 --- a/CMake/doxyfile.in +++ b/CMake/doxyfile.in @@ -132,6 +132,7 @@ INPUT = @VTKm_SOURCE_DIR@/README.md INPUT += @VTKm_SOURCE_DIR@/CONTRIBUTING.md INPUT += @VTKm_SOURCE_DIR@/docs/CodingConventions.md INPUT += @VTKm_SOURCE_DIR@/vtkm +INPUT += @VTKm_BINARY_DIR@/include USE_MDFILE_AS_MAINPAGE = README.md @@ -328,13 +329,16 @@ PERLMOD_MAKEVAR_PREFIX = ENABLE_PREPROCESSING = YES -MACRO_EXPANSION = NO +# Turning macro expansion on is required to work around issue with breathe +# (for Sphinx documentation) parsing function modifiers. +# https://github.com/breathe-doc/breathe/issues/905 +MACRO_EXPANSION = YES EXPAND_ONLY_PREDEF = NO SEARCH_INCLUDES = YES -INCLUDE_PATH = @VTKm_SOURCE_DIR@ @VTKm_BINARY_DIR@ +INCLUDE_PATH = @VTKm_SOURCE_DIR@ @VTKm_BINARY_DIR@/include INCLUDE_FILE_PATTERNS = diff --git a/docs/users-guide/base-types.rst b/docs/users-guide/base-types.rst index c3b9b9151..2baccc2d5 100644 --- a/docs/users-guide/base-types.rst +++ b/docs/users-guide/base-types.rst @@ -120,7 +120,7 @@ A ``Vec`` also supports basic arithmetic operators so that it can be used much l .. load-example:: SimpleVectorTypes :file: GuideExampleCoreDataTypes.cxx - :caption: Simple use of ``Vec`` objects.} + :caption: Simple use of ``Vec`` objects. You can also specify the precision for each of these vector types by appending the bit size of each component. For example, :type:`vtkm::Vec3f_32` and :type:`vtkm::Vec3f_64` represent 3-component floating point vectors with each component being 32 bits and 64 bits respectively. diff --git a/docs/users-guide/color-table-presets.rst b/docs/users-guide/color-table-presets.rst new file mode 100644 index 000000000..b18e37e78 --- /dev/null +++ b/docs/users-guide/color-table-presets.rst @@ -0,0 +1,21 @@ +.. DO NOT EDIT! +.. Created by GuideExampleColorTables test. + +.. |Black---Blue---White| image:: images/color-tables/Black---Blue---White.png +.. |Black-Body-Radiation| image:: images/color-tables/Black-Body-Radiation.png +.. |Blue---Green---Orange| image:: images/color-tables/Blue---Green---Orange.png +.. |Blue-to-Orange| image:: images/color-tables/Blue-to-Orange.png +.. |Cold-and-Hot| image:: images/color-tables/Cold-and-Hot.png +.. |Cool-to-Warm| image:: images/color-tables/Cool-to-Warm.png +.. |Cool-to-Warm-Extended| image:: images/color-tables/Cool-to-Warm-Extended.png +.. |Default| image:: images/color-tables/Default.png +.. |Gray-to-Red| image:: images/color-tables/Gray-to-Red.png +.. |Green| image:: images/color-tables/Green.png +.. |Inferno| image:: images/color-tables/Inferno.png +.. |Jet| image:: images/color-tables/Jet.png +.. |Plasma| image:: images/color-tables/Plasma.png +.. |Rainbow-Desaturated| image:: images/color-tables/Rainbow-Desaturated.png +.. |Rainbow-Uniform| image:: images/color-tables/Rainbow-Uniform.png +.. |Viridis| image:: images/color-tables/Viridis.png +.. |X-Ray| image:: images/color-tables/X-Ray.png +.. |Yellow---Gray---Blue| image:: images/color-tables/Yellow---Gray---Blue.png diff --git a/docs/users-guide/dataset.rst b/docs/users-guide/dataset.rst new file mode 100644 index 000000000..17ee8ab91 --- /dev/null +++ b/docs/users-guide/dataset.rst @@ -0,0 +1,592 @@ +============================== +Data Sets +============================== + +.. index:: data set + +A *data set*, implemented with the :class:`vtkm::cont::DataSet` class, +contains and manages the geometric data structures that |VTKm| operates on. + +.. index:: + single: cell set + single: field + single: coordinate system + +.. doxygenclass:: vtkm::cont::DataSet + +In addition to the base :class:`vtkm::cont::DataSet`, |VTKm| provides :class:`vtkm::cont::PartitionedDataSet` to represent data partitioned into multiple domains. +A :class:`vtkm::cont::PartitionedDataSet` is implemented as a collection of :class:`vtkm::cont::DataSet` objects. +Partitioned data sets are described later in :secref:`dataset:Partitioned Data Sets`. + + +------------------------------ +Building Data Sets +------------------------------ + +.. index:: data set ; building + +Before we go into detail on the cell sets, fields, and coordinate systems that make up a data set in |VTKm|, let us first discuss how to build a data set. +One simple way to build a data set is to load data from a file using the `vtkm::io` module. +Reading files is discussed in detail in Chapter~\ref{chap:FileIO}. + +.. todo:: Add previous reference. + +This section describes building data sets of different types using a set of +classes named `DataSetBuilder*`, which provide a convenience layer +on top of :class:`vtkm::cont::DataSet` to make it easier to create data sets. + +.. didyouknow:: + To simplify the introduction of :class:`vtkm::cont::DataSet` objects, this section uses the simplest mechanisms. + In many cases this involves loading data in a `std::vector` and passing that to |VTKm|, which usually causes the data to be copied. + This is not the most efficient method to load data into |VTKm|. + Although it is sufficient for small data or data that come from a "slow" source, such as a file, it might be a bottleneck for large data generated by another library. + It is possible to adapt |VTKm|'s :class:`vtkm::cont::DataSet` to externally defined data. + This is done by wrapping existing data into what is called `ArrayHandle`, but this is a more advanced topic that will not be addressed in this chapter. + `ArrayHandle` objects are introduced in Chapter \ref{chap:BasicArrayHandles} and more adaptive techniques are described in later chapters. + +.. todo:: Add previous reference. + +Creating Uniform Grids +============================== + +.. index:: + single: uniform grid + single: regular grid + single: image + +Uniform grids are meshes that have a regular array structure with points uniformly spaced parallel to the axes. +Uniform grids are also sometimes called regular grids or images. + +The :class:`vtkm::cont::DataSetBuilderUniform` class can be used to easily create 2- or 3-dimensional uniform grids. +:class:`vtkm::cont::DataSetBuilderUniform` has several versions of a method named :func:`vtkm::cont::DataSetBuilderUniform::Create` that takes the number of points in each dimension, the origin, and the spacing. +The origin is the location of the first point of the data (in the lower left corner), and the spacing is the distance between points in the x, y, and z directions. + +.. doxygenclass:: vtkm::cont::DataSetBuilderUniform + :members: + +The following example creates a :class:`vtkm::cont::DataSet` containing a uniform grid of :math:`101 \times 101 \times 26` points. + +.. load-example:: CreateUniformGrid + :file: GuideExampleDataSetCreation.cxx + :caption: Creating a uniform grid.}{.cxx} + +If not specified, the origin will be at the coordinates :math:`(0,0,0)` and the spacing will be :math:`1` in each direction. +Thus, in the previous example the width, height, and depth of the mesh in physical space will be :math:`100`, :math:`100`, and :math`25`, respectively, and the mesh will be centered at :math:`(50, 50, 12.5)`. +Let us say we actually want a mesh of the same dimensions, but we want the :math:`z` direction to be stretched out so that the mesh will be the same size in each direction, and we want the mesh centered at the origin. + +.. load-example:: CreateUniformGridCustomOriginSpacing + :file: GuideExampleDataSetCreation.cxx + :caption: Creating a uniform grid with custom origin and spacing. + +Creating Rectilinear Grids +============================== + +.. index:: rectilinear grid + +A rectilinear grid is similar to a uniform grid except that a rectilinear grid can adjust the spacing between adjacent grid points. +This allows the rectilinear grid to have tighter sampling in some areas of space, but the points are still constrained to be aligned with the axes and each other. +The irregular spacing of a rectilinear grid is specified by providing a separate array each for the x, y, and z coordinates. + +The :class:`vtkm::cont::DataSetBuilderRectilinear` class can be used to easily create +2- or 3-dimensional rectilinear grids. +:class:`vtkm::cont::DataSetBuilderRectilinear` has several versions of a method +named :func:`vtkm::cont::DataSetBuilderRectilinear::Create` that takes these coordinate arrays and builds a +:class:`vtkm::cont::DataSet` out of them. The arrays can be supplied as either +standard C arrays or as `std::vector` objects, in which case the +data in the arrays are copied into the :class:`vtkm::cont::DataSet`. These +arrays can also be passed as :class:`vtkm::cont::ArrayHandle` objects (introduced later in this book), in which +case the data are shallow copied. + +.. doxygenclass:: vtkm::cont::DataSetBuilderRectilinear + :members: + +The following example creates a :class:`vtkm::cont::DataSet` containing a rectilinear +grid with :math:`201 \times 201 \times 101` points with different irregular +spacing along each axis. + + +.. load-example:: CreateRectilinearGrid + :file: GuideExampleDataSetCreation.cxx + :caption: Creating a rectilinear grid. + +Creating Explicit Meshes +============================== + +.. index:: + single: explicit mesh + single: unstructured grid + +An explicit mesh is an arbitrary collection of cells with arbitrary connections. +It can have multiple different types of cells. +Explicit meshes are also known as unstructured grids. +Explicit meshes can contain cells of different shapes. +The shapes that |VTKm| currently supports are listed in :numref:`fig:CreateExplicitMeshesCellShapes`. +Each shape is identified using either a numeric identifier, provided by |VTKm| with identifiers of the form ``vtkm::CELL_SHAPE_*`` or special tag structures of the form ``vtkm::CellSetTag*``. +Cell shapes are discussed in detail in ???. + +.. todo:: Add cell shape reference above. + +.. figure:: images/CellConnections.png + :width: 100% + :name: fig:CreateExplicitMeshesCellShapes + + Basic Cell Shapes. + +.. + .. |CellConnectionsVertex| image:: images/CellConnectionsVertex.png + .. |CellConnectionsLine| image:: images/CellConnectionsLine.png + .. |CellConnectionsPolyLine| image:: images/CellConnectionsPolyLine.png + .. |CellConnectionsTriangle| image:: images/CellConnectionsTriangle.png + .. |CellConnectionsPolygon| image:: images/CellConnectionsPolygon.png + .. |CellConnectionsQuadrilateral| image:: images/CellConnectionsQuadrilateral.png + .. |CellConnectionsTetrahedron| image:: images/CellConnectionsTetrahedron.png + .. |CellConnectionsHexahedron| image:: images/CellConnectionsHexahedron.png + .. |CellConnectionsWedge| image:: images/CellConnectionsWedge.png + .. |CellConnectionsPyramid| image:: images/CellConnectionsPyramid.png + + .. table:: Basic Cell Shapes + :name: ExplicitCellShapes + :width: 100% + + +----------------------------------------------+----------------------------------------------+----------------------------------------------+ + | :enumerator:`vtkm::CELL_SHAPE_VERTEX` | :enumerator:`vtkm::CELL_SHAPE_Line` | :enumerator:`vtkm::CELL_SHAPE_POLY_LINE` | + | :struct:`vtkm::CellShapeTagVertex` | :struct:`vtkm::CellShapeTagLine` | :struct:`vtkm::CellShapeTagPolyLine` | + | |CellConnectionsVertex| | |CellConnectionsLine| | |CellConnectionsPolyLine| | + +----------------------------------------------+----------------------------------------------+----------------------------------------------+ + | :enumerator:`vtkm::CELL_SHAPE_TRIANGLE` | :enumerator:`vtkm::CELL_SHAPE_POLYGON` | :enumerator:`vtkm::CELL_SHAPE_QUADRILATERAL` | + | :struct:`vtkm::CellShapeTagTriangle` | :struct:`vtkm::CellShapeTagPolygon` | :struct:`vtkm::CellShapeTagQuadrilateral` | + | |CellConnectionsTriangle| | |CellConnectionsPolygon| | |CellConnectionsQuadrilateral| | + +----------------------------------------------+----------------------------------------------+----------------------------------------------+ + | :enumerator:`vtkm::CELL_SHAPE_TETRAHEDRON` | :enumerator:`vtkm::CELL_SHAPE_HEXAHEDRON` | :enumerator:`vtkm::CELL_SHAPE_WEDGE` | + | :struct:`vtkm::CellShapeTagTetrahedron` | :struct:`vtkm::CellShapeTagHexahedron` | :struct:`vtkm::CellShapeTagWedge` | + | |CellConnectionsTetrahedron| | |CellConnectionsHexahedron| | |CellConnectionsWedge| | + +----------------------------------------------+----------------------------------------------+----------------------------------------------+ + | | :enumerator:`vtkm::CELL_SHAPE_PYRAMID` | | + | | :struct:`vtkm::CellShapeTagPyramid` | | + | | |CellConnectionsPyramid| | | + +----------------------------------------------+----------------------------------------------+----------------------------------------------+ + +.. figure:: images/ExplicitCellConnections.png + :width: 100% + :name: fig:ExplicitMesh + + An example explicit mesh. + +The cells of an explicit mesh are defined with the following 3 arrays, which are depicted graphically in :numref:`fig:ExplicitMesh`. + +.. index:: explicit mesh ; shapes + +Shapes + An array of ids identifying the shape of the cell. + Each value is a :type:`vtkm::UInt8` and should be set to one of the ``vtkm::CELL_SHAPE_*`` constants. + The shapes and their identifiers are shown in :numref:`fig:CreateExplicitMeshesCellShapes`. + The size of this array is equal to the number of cells in the set. + +.. index:: explicit mesh ; connectivity + +Connectivity + An array that lists all the points that comprise each cell. + Each entry in the array is a :type:`vtkm::Id` giving the point id associated with a vertex of a cell. + The points for each cell are given in a prescribed order for each shape, which is also shown in :numref:`fig:CreateExplicitMeshesCellShapes`. + The point indices are stored consecutively from the first cell to the last. + +.. index:: explicit mesh ; offsets + +Offsets + An array of :type:`vtkm::Id`'s pointing to the index in the connectivity array where the points for a particular cell starts. + The size of this array is equal to the number of cells in the set plus 1. + The first entry is expected to be 0 (since the connectivity of the first cell is at the start of the connectivity array). + The last entry, which does not correspond to any cell, should be the size of the connectivity array. + +One important item that is missing from this list of arrays is a count of the number of indices associated with each cell. +This is not explicitly represented in |VTKm|'s mesh structure because it can be implicitly derived from the offsets array by subtracting consecutive entries. +However, it is usually the case when building an explicit mesh that you will have an array of these counts rather than the offsets. +It is for this reason that |VTKm| contains mechanisms to build an explicit data set with a "num indices" arrays rather than an offsets array. + +The :class:`vtkm::cont::DataSetBuilderExplicit` class can be used to create data sets with explicit meshes. +:class:`vtkm::cont::DataSetBuilderExplicit` has several versions of a method named :func:`vtkm::cont::DataSetBuilderExplicit::Create`. +Generally, these methods take the shapes, number of indices, and connectivity arrays as well as an array of point coordinates. + +.. doxygenclass:: vtkm::cont::DataSetBuilderExplicit + :members: + +The following example creates a mesh like the one shown in +:numref:`fig:ExplicitMesh`. + +.. load-example:: CreateExplicitGrid + :file: GuideExampleDataSetCreation.cxx + :caption: Creating an explicit mesh with :class:`vtkm::cont::DataSetBuilderExplicit`. + +Often it is awkward to build your own arrays and then pass them to :class:`vtkm::cont::DataSetBuilderExplicit`. +There also exists an alternate builder class named :class:`vtkm::cont::DataSetBuilderExplicitIterative` that allows you to specify each cell and point one at a time rather than all at once. +This is done by calling one of the versions of :func:`vtkm::cont::DataSetBuilderExplicitIterative::AddPoint` and one of the versions of :func:`vtkm::cont::DataSetBuilderExplicitIterative::AddCell` for each point and cell, respectively. + +.. doxygenclass:: vtkm::cont::DataSetBuilderExplicitIterative + :members: + +The next example also builds the mesh shown in :numref:`fig:ExplicitMesh` except this time using :class:`vtkm::cont::DataSetBuilderExplicitIterative`. + +.. load-example:: CreateExplicitGridIterative + :file: GuideExampleDataSetCreation.cxx + :caption: Creating an explicit mesh with :class:`vtkm::cont::DataSetBuilderExplicitIterative`. + +Add Fields +============================== + +In addition to creating the geometric structure of a data set, it is usually important to add fields to the data. +Fields describe numerical data associated with the topological elements in a cell. +They often represent a physical quantity (such as temperature, mass, or volume fraction) but can also represent other information (such as indices or classifications). + +The easiest way to define fields in a data set is to use the :func:`vtkm::cont::DataSet::AddPointField` and :func:`vtkm::cont::DataSet::AddCellField` methods. +Each of these methods take a requisite field name and the array with with field data. + +Both :func:`vtkm::cont::DataSet::AddPointField` and :func:`vtkm::cont::DataSet::AddCellField` are overloaded to accept arrays of data in different structures. +Field arrays can be passed as standard C arrays or as ``std::vector``'s, in which case the data are copied. +Field arrays can also be passed in a ``ArrayHandle`` (introduced later in this book), in which case the data are not copied. + +.. doxygenfunction:: vtkm::cont::DataSet::AddPointField(const std::string&, const vtkm::cont::UnknownArrayHandle&) + +.. doxygenfunction:: vtkm::cont::DataSet::AddPointField(const std::string&, const std::vector&) + +.. doxygenfunction:: vtkm::cont::DataSet::AddPointField(const std::string&, const T*, const vtkm::Id&) + +.. doxygenfunction:: vtkm::cont::DataSet::AddCellField(const std::string&, const vtkm::cont::UnknownArrayHandle&) + +.. doxygenfunction:: vtkm::cont::DataSet::AddCellField(const std::string&, const std::vector&) + +.. doxygenfunction:: vtkm::cont::DataSet::AddCellField(const std::string&, const T*, const vtkm::Id&) + +The following (somewhat contrived) example defines fields for a uniform grid that identify which points and cells are on the boundary of the mesh. + +.. load-example:: AddFieldData + :file: GuideExampleDataSetCreation.cxx + :caption: Adding fields to a :class:`vtkm::cont::DataSet`. + + +------------------------------ +Cell Sets +------------------------------ + +.. index:: cell set +.. index:: data set ; cell set + +.. index:: + triple: cell; shape; point + triple: cell; shape; edge + triple: cell; shape; face + +A cell set determines the topological structure of the data in a data set. + +.. doxygenclass:: vtkm::cont::CellSet + :members: + +3D cells are made up of *points*, *edges*, and *faces*. +(2D cells have only points and edges, and 1D cells have only points.) +:numref:`fig:CellTopology` shows the relationship between a cell's shape and these topological elements. +The arrangement of these points, edges, and faces is defined by the *shape* of the cell, which prescribes a specific ordering of each. +The basic cell shapes provided by |VTKm| are discussed in detail in Section~\ref{sec:CellShapeTagsIds} starting on page~\pageref{sec:CellShapeTagsIds}. + +.. todo:: Add cell shape reference above. + +.. figure:: images/CellConstituents.png + :width: 50% + :name: fig:CellTopology + + The relationship between a cell shape and its topological elements (points, edges, and faces). + +There are multiple ways to express the connections of a cell set, each with +different benefits and restrictions. These different cell set types are +managed by different cell set classes in |VTKm|. All |VTKm| cell set classes +inherit from :class:`vtkm::cont::CellSet`. The two basic types of cell sets are +structured and explicit, and there are several variations of these types. + +Structured Cell Sets +============================== + +.. index:: + single: cell set; structured + single: structured cell set + +.. doxygenclass:: vtkm::cont::CellSetStructured + :members: + +The number of points in a :class:`vtkm::cont::CellSetStructured` is implicitly :math:`i \times j \times k` and the number of cells is implicitly :math:`(i-1) \times (j-1) \times (k-1)` (for 3D grids). +:numref:`fig:CellSetStructured` demonstrates this arrangement. + +.. figure:: images/StructuredCellSet.png + :width: 100% + :name: fig:CellSetStructured + + The arrangement of points and cells in a 3D structured grid. + +The big advantage of using :class:`vtkm::cont::CellSetStructured` to define a cell set is that it is very space efficient because the entire topology can be defined by the three integers specifying the dimensions. +Also, algorithms can be optimized for :class:`vtkm::cont::CellSetStructured`'s regular nature. +However, :class:`vtkm::cont::CellSetStructured`'s strictly regular grid also limits its applicability. +A structured cell set can only be a dense grid of lines, quadrilaterals, or hexahedra. +It cannot represent irregular data well. + +Many data models in other software packages, such as the one for VTK, make a distinction between uniform, rectilinear, and curvilinear grids. +|VTKm|'s cell sets do not. +All three of these grid types are represented by :class:`vtkm::cont::CellSetStructured`. +This is because in a |VTKm| data set the cell set and the coordinate system are defined independently and used interchangeably. +A structured cell set with uniform point coordinates makes a uniform grid. +A structured cell set with point coordinates defined irregularly along coordinate axes makes a rectilinear grid. +And a structured cell set with arbitrary point coordinates makes a curvilinear grid. +The point coordinates are defined by the data set's coordinate system, which is discussed in :secref:`dataset:Coordinate Systems`. + +Explicit Cell Sets +============================== + +.. index:: + single: cell set; explicit + single: explicit cell set + +.. doxygenclass:: vtkm::cont::CellSetExplicit + :members: + +The types of cell sets are listed in :numref:`fig:ExplicitCellSetShapes`. + + +.. figure:: images/CellConnections.png + :width: 100% + :name: fig:ExplicitCellSetShapes + + Basic Cell Shapes in a :class:`vtkm::cont::CellSetExplicit`. + +An explicit cell set is defined with a minimum of three arrays. +The first array identifies the shape of each cell. +(Identifiers for cell shapes are shown in :numref:`fig:ExplicitCellSetShapes`.) +The second array has a sequence of point indices that make up each cell. +The third array identifies an offset into the second array where the point indices for each cell is found plus an extra entry at the end set to the size of the second array. +:numref:`fig:CellSetExplicit` shows a simple example of an explicit cell set. + +.. figure:: images/ExplicitCellConnections.png + :width: 100% + :name: fig:CellSetExplicit + + Example of cells in a :class:`vtkm::cont::CellSetExplicit` and the arrays that define them. + +An explicit cell set can also identify the number of indices defined for each cell by subtracting consecutive entries in the offsets array. +It is often the case when creating a :class:`vtkm::cont::CellSetExplicit` that you have an array containing the number of indices rather than the offsets. +Such an array can be converted to an offsets array that can be used with :class:`vtkm::cont::CellSetExplicit` by using the :func:`vtkm::cont::ConvertNumComponentsToOffsets` convenience function. + +.. doxygenfunction:: vtkm::cont::ConvertNumComponentsToOffsets(const vtkm::cont::UnknownArrayHandle&, vtkm::cont::ArrayHandle&, vtkm::Id&, vtkm::cont::DeviceAdapterId) + +:class:`vtkm::cont::CellSetExplicit` is a powerful representation for a cell set +because it can represent an arbitrary collection of cells. However, because +all connections must be explicitly defined, +:class:`vtkm::cont::CellSetExplicit` requires a significant amount of memory to +represent the topology. + +.. index:: + single: cell set; single type + single: explicit cell set; single type + single: single type cell set + +An important specialization of an explicit cell set is +:class:`vtkm::cont::CellSetSingleType`. + +.. doxygenclass:: vtkm::cont::CellSetSingleType + :members: + +Cell Set Permutations +============================== + +.. index:: + single: cell set; permutation + single: permutation cell set + +To rearrange, and possibly subsample, cells in a ``CellSet``, use :type:`vtkm::cont::CellSetPermutation` to define a new set without copying. + +.. doxygenclass:: vtkm::cont::CellSetPermutation + :members: + +.. didyouknow:: + Although :class:`vtkm::cont::CellSetPermutation` can mask cells, it cannot mask points. + All points from the original cell set are available in the permuted cell set regardless of whether they are used. + +The following example uses :class:`vtkm::cont::CellSetPermutation` with a counting array to expose every tenth cell. +This provides a simple way to subsample a data set. + +.. load-example:: CreateCellSetPermutation + :file: GuideExampleDataSetCreation.cxx + :caption: Subsampling a data set with :class:`vtkm::cont::CellSetPermutation`. + +Cell Set Extrude +============================== + +.. doxygenclass:: vtkm::cont::CellSetExtrude + :members: + +.. figure:: images/ExtrudedCellSet.png + :width: 100% + :name: fig:CellSetExtruded + + An example of an extruded wedge from XZ-plane coordinates. + Six wedges are extracted from three XZ-plane points. + +The extruded mesh is advantageous because it is represented on-the-fly as required, so no additional memory is required. +In contrast other forms of cell sets, such as :class:`vtkm::cont::CellSetExplicit`, need to be explicitly constructed by replicating the vertices and cells. +:numref:`fig:CellSetExtruded` shows an example of six wedges extruded from three 2-dimensional coordinates. + +Unknown Cell Sets +============================== + +Each of the aforementioned cell set types are represented by a different class. +A :class:`vtkm::cont::DataSet` object must hold one of these cell set objects that represent the cell structure. +The actual object used is not determined until run time. + +The :class:`vtkm::cont::DataSet` object manages the cell set object with :class:`vtkm::cont::UnknownCellSet`. +When you call :func:`vtkm::cont::DataSet::GetCellSet`, it returns a :class:`vtkm::cont::UnknownCellSet`. + +The :class:`vtkm::cont::UnknownCellSet` object provides mechanisms to query the cell set, identify its type, and cast it to one of the concrete ``CellSet`` types. +See Chapter \ref{chap:UnknownCellSet} for details on working with :class:`vtkm::cont::UnknownCellSet`. + +.. todo:: Add previous reference to UnknownCellSet chapter. + + +------------------------------ +Fields +------------------------------ + +.. index:: + single: field + single: data set; field + +A field on a data set provides a value on every point in space on the mesh. +Fields are often used to describe physical properties such as pressure, temperature, mass, velocity, and much more. +Fields are represented in a |VTKm| data set as an array where each value is associated with a particular element type of a mesh (such as points or cells). +This association of field values to mesh elements and the structure of the cell set determines how the field is interpolated throughout the space of the mesh. + +Fields are manged by the :class:`vtkm::cont::Field` class. + +.. doxygenclass:: vtkm::cont::Field + +Fields are identified by a simple name string. + +.. doxygenfunction:: vtkm::cont::Field::GetName + +The :class:`vtkm::cont::Field` object internally holds a reference to an array in a type-agnostic way. +Filters and other |VTKm| units will determine the type of the array and pull it out of the :class:`vtkm::cont::Field`. + +.. doxygenfunction:: vtkm::cont::Field::GetData() const + +The field data is associated with a particular type of element of a mesh such as points, cells, or the whole mesh. + +.. doxygenfunction:: vtkm::cont::Field::GetAssociation + +Associations are identified by the :enum:`vtkm::cont::Field::Association` enumeration. + +.. doxygenenum:: vtkm::cont::Field::Association + +The :class:`vtkm::cont::Field` class also has several convenience methods for querying the association. + +.. doxygenfunction:: vtkm::cont::Field::IsPointField + +.. doxygenfunction:: vtkm::cont::Field::IsCellField + +.. doxygenfunction:: vtkm::cont::Field::IsWholeDataSetField + +.. doxygenfunction:: vtkm::cont::Field::IsPartitionsField + +.. doxygenfunction:: vtkm::cont::Field::IsGlobalField + +.. index:: double: range; field + +:class:`vtkm::cont::Field` has a convenience method named :func:`vtkm::cont::Field::GetRange` that finds the range of values stored in the field array. + +.. doxygenfunction:: vtkm::cont::Field::GetRange() const + +Details on how to get data from a :class:`vtkm::cont::ArrayHandle` them is given in Chapter \ref{chap:AccessingAllocatingArrays}. + +.. todo:: Fix above reference to array handle chapter. + + +------------------------------ +Coordinate Systems +------------------------------ + +.. index:: + single: coordinate system + single: data set; coordinate system + +A coordinate system determines the location of a mesh's elements in space. +The spatial location is described by providing a 3D vector at each point that gives the coordinates there. +The point coordinates can then be interpolated throughout the mesh. + +.. doxygenclass:: vtkm::cont::CoordinateSystem + +In addition to all the methods provided by the :class:`vtkm::cont::Field` superclass, the :class:`vtkm::cont::CoordinateSystem` also provides a :func:`vtkm::cont::CoordinateSystem::GetBounds` convenience method that returns a :class:`vtkm::Bounds` object giving the spatial bounds of the coordinate system. + +.. doxygenfunction:: vtkm::cont::CoordinateSystem::GetBounds + +It is typical for a :class:`vtkm::cont::DataSet` to have one coordinate system defined, but it is possible to define multiple coordinate systems. +This is helpful when there are multiple ways to express coordinates. +For example, positions in geographic may be expressed as Cartesian coordinates or as latitude-longitude coordinates. +Both are valid and useful in different ways. + +It is also valid to have a :class:`vtkm::cont::DataSet` with no coordinate system. +This is useful when the structure is not rooted in physical space. +For example, if the cell set is representing a graph structure, there might not be any physical space that has meaning for the graph. + + +------------------------------ +Partitioned Data Sets +------------------------------ + +.. index:: + single: partitioned data set + single: data set; partitioned + +.. doxygenclass:: vtkm::cont::PartitionedDataSet + :members: + +The following example creates a :class:`vtkm::cont::PartitionedDataSet` containing two uniform grid data sets. + +.. load-example:: CreatePartitionedDataSet + :file: GuideExampleDataSetCreation.cxx + :caption: Creating a :class:`vtkm::cont::PartitionedDataSet`. + +It is always possible to retrieve the independent blocks in a :class:`vtkm::cont::PartitionedDataSet`, from which you can iterate and get information about the data. +However, |VTKm| provides several helper functions to collect metadata information about the collection as a whole. + +.. doxygenfunction:: vtkm::cont::BoundsCompute(const vtkm::cont::DataSet&, vtkm::Id) + +.. doxygenfunction:: vtkm::cont::BoundsCompute(const vtkm::cont::PartitionedDataSet&, vtkm::Id) + +.. doxygenfunction:: vtkm::cont::BoundsCompute(const vtkm::cont::DataSet&, const std::string&) + +.. doxygenfunction:: vtkm::cont::BoundsCompute(const vtkm::cont::PartitionedDataSet&, const std::string&) + +.. doxygenfunction:: vtkm::cont::BoundsGlobalCompute(const vtkm::cont::DataSet&, vtkm::Id) + +.. doxygenfunction:: vtkm::cont::BoundsGlobalCompute(const vtkm::cont::PartitionedDataSet&, vtkm::Id) + +.. doxygenfunction:: vtkm::cont::BoundsGlobalCompute(const vtkm::cont::DataSet&, const std::string&) + +.. doxygenfunction:: vtkm::cont::BoundsGlobalCompute(const vtkm::cont::PartitionedDataSet&, const std::string&) + +.. doxygenfunction:: vtkm::cont::FieldRangeCompute(const vtkm::cont::DataSet&, const std::string&, vtkm::cont::Field::Association) + +.. doxygenfunction:: vtkm::cont::FieldRangeCompute(const vtkm::cont::PartitionedDataSet&, const std::string&, vtkm::cont::Field::Association) + +.. doxygenfunction:: vtkm::cont::FieldRangeGlobalCompute(const vtkm::cont::DataSet&, const std::string&, vtkm::cont::Field::Association) + +.. doxygenfunction:: vtkm::cont::FieldRangeGlobalCompute(const vtkm::cont::PartitionedDataSet&, const std::string&, vtkm::cont::Field::Association) + +The following example illustrates a spatial bounds query and a field range query on a :class:`vtkm::cont::PartitionedDataSet`. + +.. load-example:: QueryPartitionedDataSet + :file: GuideExampleDataSetCreation.cxx + :caption: Queries on a :class:`vtkm::cont::PartitionedDataSet`. + +.. didyouknow:: + The aforementioned functions for querying a :class:`vtkm::cont::PartitionedDataSet` object also work on :class:`vtkm::cont::DataSet` objects. + This is particularly useful with the :func:`vtkm::cont::BoundsGlobalCompute` and :func:`vtkm::cont::FieldRangeGlobalCompute` functions to manage distributed parallel objects. + +Filters can be executed on :class:`vtkm::cont::PartitionedDataSet` objects in a similar way they are executed on :class:`vtkm::cont::DataSet` objects. +In both cases, the :func:`vtkm::cont::Filter::Execute` method is called on the filter giving data object as an argument. + +.. load-example:: FilterPartitionedDataSet + :file: GuideExampleDataSetCreation.cxx + :caption: Applying a filter to multi block data. diff --git a/docs/users-guide/error-handling.rst b/docs/users-guide/error-handling.rst new file mode 100644 index 000000000..46b083fa3 --- /dev/null +++ b/docs/users-guide/error-handling.rst @@ -0,0 +1,114 @@ +============================== +Error Handling +============================== + +|VTKm| contains several mechanisms for checking and reporting error conditions. + +------------------------------ +Runtime Error Exceptions +------------------------------ + +.. index:: + double: errors; control environment + +|VTKm| uses exceptions to report errors. +All exceptions thrown by |VTKm| will be a subclass of :class:`vtkm::cont::Error`. +For simple error reporting, it is possible to simply catch a :class:`vtkm::cont::Error` and report the error message string reported by the :func:`vtkm::cont::Error::GetMessage` method. + +.. load-example:: CatchingErrors + :file: GuideExampleErrorHandling.cxx + :caption: Simple error reporting. + +.. doxygenclass:: vtkm::cont::Error + :members: + +There are several subclasses to :class:`vtkm::cont::Error`. +The specific subclass gives an indication of the type of error that occurred when the exception was thrown. +Catching one of these subclasses may help a program better recover from errors. + +.. doxygenclass:: vtkm::cont::ErrorBadAllocation + :members: + +.. doxygenclass:: vtkm::cont::ErrorBadDevice + :members: + +.. doxygenclass:: vtkm::cont::ErrorBadType + :members: + +.. doxygenclass:: vtkm::cont::ErrorBadValue + :members: + +.. doxygenclass:: vtkm::cont::ErrorExecution + :members: + +.. doxygenclass:: vtkm::cont::ErrorFilterExecution + :members: + +.. doxygenclass:: vtkm::cont::ErrorInternal + :members: + +.. doxygenclass:: vtkm::cont::ErrorUserAbort + :members: + +.. doxygenclass:: vtkm::io::ErrorIO + :members: + + +------------------------------ +Asserting Conditions +------------------------------ + +.. index:: + double: errors; assert + +In addition to the aforementioned error signaling, the ``vtkm/Assert.h`` header file defines a macro named :c:macro:`VTKM_ASSERT`. +This macro behaves the same as the POSIX :c:macro:`assert` macro. +It takes a single argument that is a condition that is expected to be true. +If it is not true, the program is halted and a message is printed. +Asserts are useful debugging tools to ensure that software is behaving and being used as expected. + +.. load-example:: Assert + :file: GuideExampleErrorHandling.cxx + :caption: Using :c:macro:`VTKM_ASSERT`. + +.. didyouknow:: + Like the POSIX :c:macro:`assert`, if the :c:macro:`NDEBUG` macro is defined, then :c:macro:`VTKM_ASSERT` will become an empty expression. + Typically :c:macro:`NDEBUG` is defined with a compiler flag (like ``-DNDEBUG``) for release builds to better optimize the code. + CMake will automatically add this flag for release builds. + +.. commonerrors:: + A helpful warning provided by many compilers alerts you of unused variables. + (This warning is commonly enabled on |VTKm| regression test nightly builds.) + If a function argument is used only in a :c:macro:`VTKM_ASSERT`, then it will be required for debug builds and be unused in release builds. + To get around this problem, add a statement to the function of the form ``(void)variableName;``. + This statement will have no effect on the code generated but will suppress the warning for release builds. + + +------------------------------ +Compile Time Checks +------------------------------ + +.. index:: + single: assert; static + single: static assert + +Because |VTKm| makes heavy use of C++ templates, it is possible that these templates could be used with inappropriate types in the arguments. +Using an unexpected type in a template can lead to very confusing errors, so it is better to catch such problems as early as possible. +The :c:macro:`VTKM_STATIC_ASSERT` macro, defined in ``vtkm/StaticAssert.h`` makes this possible. +This macro takes a constant expression that can be evaluated at compile time and verifies that the result is true. + +In the following example, :c:macro:`VTKM_STATIC_ASSERT` and its sister macro :c:macro:`VTKM_STATIC_ASSERT_MSG`, which allows you to give a descriptive message for the failure, are used to implement checks on a templated function that is designed to work on any scalar type that is represented by 32 or more bits. + +.. load-example:: StaticAssert + :file: GuideExampleErrorHandling.cxx + :caption: Using :c:macro:`VTKM_STATIC_ASSERT`. + +.. didyouknow:: + In addition to the several trait template classes provided by |VTKm| to introspect C++ types, the C++ standard ``type_traits`` header file contains several helpful templates for general queries on types. + :numref:`ex:StaticAssert` demonstrates the use of one such template: ``std::is_same``. + +.. commonerrors:: + Many templates used to introspect types resolve to the tags ``std::true_type`` and ``std::false_type`` rather than the constant values ``true`` and ``false`` that :c:macro:`VTKM_STATIC_ASSERT` expects. + The ``std::true_type`` and ``std::false_type`` tags can be converted to the Boolean literal by adding ``::value`` to the end of them. + Failing to do so will cause :c:macro:`VTKM_STATIC_ASSERT` to behave incorrectly. + :numref:`ex:StaticAssert` demonstrates getting the Boolean literal from the result of ``std::is_same``. diff --git a/docs/users-guide/examples/CMakeLists.txt b/docs/users-guide/examples/CMakeLists.txt index c6375e843..139bef937 100644 --- a/docs/users-guide/examples/CMakeLists.txt +++ b/docs/users-guide/examples/CMakeLists.txt @@ -9,11 +9,36 @@ ##============================================================================ set(examples + GuideExampleColorTables.cxx GuideExampleCoreDataTypes.cxx + GuideExampleInitialization.cxx + GuideExampleIO.cxx + GuideExampleProvidedFilters.cxx + GuideExampleRendering.cxx + GuideExampleRuntimeDeviceTracker.cxx + GuideExampleTimer.cxx ) +set(examples_device + GuideExampleDataSetCreation.cxx # Uses CellSetPartitioned + GuideExampleErrorHandling.cxx # Calls worklet + ) +set(extra_libs) + +vtkm_find_gl(OPTIONAL GL GLUT) +if(TARGET GLUT::GLUT) + list(APPEND examples + GuideExampleRenderingInteractive.cxx + ) + list(APPEND extra_libs OpenGL::GL GLUT::GLUT) +else() + message("Not building OpenGL tutorial examples because GL/GLUT not found.") +endif() vtkm_unit_tests( SOURCES ${examples} + DEVICE_SOURCES ${examples_device} + LIBRARIES ${extra_libs} + TEST_ARGS "--no-interaction" ) # Special example that is an encapsulated program diff --git a/docs/users-guide/examples/GuideExampleColorTables.cxx b/docs/users-guide/examples/GuideExampleColorTables.cxx new file mode 100644 index 000000000..0a8e0a4b5 --- /dev/null +++ b/docs/users-guide/examples/GuideExampleColorTables.cxx @@ -0,0 +1,111 @@ +//============================================================================ +// Copyright (c) Kitware, Inc. +// All rights reserved. +// See LICENSE.txt 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 +#include + +#include + +#include + +#include + +namespace +{ + +static const vtkm::Id TABLE_IMAGE_WIDTH = 150; +static const vtkm::Id TABLE_IMAGE_HEIGHT = 20; + +std::string FilenameFriendly(const std::string& name) +{ + std::string filename; + for (auto&& ch : name) + { + if (((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')) || + ((ch >= '0') && (ch <= '9'))) + { + filename.push_back(ch); + } + else + { + filename.push_back('-'); + } + } + return filename; +} + +void CreateColorTableImage(const std::string& name) +{ + std::cout << "Creating color table " << name << std::endl; + + vtkm::cont::ColorTable colorTable(name); + + // Create a CanvasRayTracer simply for the color buffer and the ability to + // write out images. + vtkm::rendering::CanvasRayTracer canvas(TABLE_IMAGE_WIDTH, TABLE_IMAGE_HEIGHT); + using ColorBufferType = vtkm::rendering::CanvasRayTracer::ColorBufferType; + ColorBufferType colorBuffer = canvas.GetColorBuffer(); + ColorBufferType::WritePortalType colorPortal = colorBuffer.WritePortal(); + VTKM_TEST_ASSERT(colorPortal.GetNumberOfValues() == + TABLE_IMAGE_WIDTH * TABLE_IMAGE_HEIGHT, + "Wrong size of color buffer."); + + vtkm::cont::ArrayHandle temp; + colorTable.Sample(TABLE_IMAGE_WIDTH, temp); + + constexpr vtkm::Float32 conversionToFloatSpace = (1.0f / 255.0f); + + for (vtkm::Id j = 0; j < TABLE_IMAGE_HEIGHT; ++j) + { + auto tempPortal = temp.ReadPortal(); + for (vtkm::Id i = 0; i < TABLE_IMAGE_WIDTH; ++i) + { + auto color = tempPortal.Get(i); + vtkm::Vec4f_32 t(color[0] * conversionToFloatSpace, + color[1] * conversionToFloatSpace, + color[2] * conversionToFloatSpace, + color[3] * conversionToFloatSpace); + colorPortal.Set(j * TABLE_IMAGE_WIDTH + i, t); + } + } + + canvas.SaveAs("color-tables/" + FilenameFriendly(name) + ".png"); +} + +void DoColorTables() +{ +#ifndef VTKM_MSVC + // Disabled for MSVC because POSIX mkdir is not supported. + // We can use std::filestyem::create_directories later when we support C++17. + mkdir("color-tables", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); + + std::ofstream rstTable("color-tables/color-table-presets.rst", + std::ios::out | std::ios::trunc); + rstTable << ".. DO NOT EDIT!\n"; + rstTable << ".. Created by GuideExampleColorTables test.\n"; + rstTable << "\n"; + + vtkm::cont::ColorTable table; + std::set names = table.GetPresets(); + for (auto& n : names) + { + CreateColorTableImage(n); + rstTable << ".. |" << FilenameFriendly(n) << "| image:: images/color-tables/" + << FilenameFriendly(n) << ".png\n"; + } +#endif +} + +} // anonymous namespace + +int GuideExampleColorTables(int argc, char* argv[]) +{ + return vtkm::cont::testing::Testing::Run(DoColorTables, argc, argv); +} diff --git a/docs/users-guide/examples/GuideExampleDataSetCreation.cxx b/docs/users-guide/examples/GuideExampleDataSetCreation.cxx new file mode 100644 index 000000000..ad480e00b --- /dev/null +++ b/docs/users-guide/examples/GuideExampleDataSetCreation.cxx @@ -0,0 +1,652 @@ +//============================================================================ +// Copyright (c) Kitware, Inc. +// All rights reserved. +// See LICENSE.txt 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 +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include + +namespace DataSetCreationNamespace +{ + +namespace can_convert_example +{ +//// +//// BEGIN-EXAMPLE UnknownCellSetCanConvert +//// +VTKM_CONT vtkm::Id3 Get3DPointDimensions( + const vtkm::cont::UnknownCellSet& unknownCellSet) +{ + if (unknownCellSet.CanConvert>()) + { + vtkm::cont::CellSetStructured<3> cellSet; + unknownCellSet.AsCellSet(cellSet); + return cellSet.GetPointDimensions(); + } + else if (unknownCellSet.CanConvert>()) + { + vtkm::cont::CellSetStructured<2> cellSet; + unknownCellSet.AsCellSet(cellSet); + vtkm::Id2 dims = cellSet.GetPointDimensions(); + return vtkm::Id3{ dims[0], dims[1], 1 }; + } + else + { + return vtkm::Id3{ unknownCellSet.GetNumberOfPoints(), 1, 1 }; + } +} +//// +//// END-EXAMPLE UnknownCellSetCanConvert +//// +} // namespace can_convert_example + +namespace cast_and_call_for_types_example +{ + +//// +//// BEGIN-EXAMPLE UnknownCellSetCastAndCallForTypes +//// +struct Get3DPointDimensionsFunctor +{ + template + VTKM_CONT void operator()(const vtkm::cont::CellSetStructured& cellSet, + vtkm::Id3& outDims) const + { + vtkm::Vec pointDims = cellSet.GetPointDimensions(); + for (vtkm::IdComponent d = 0; d < Dims; ++d) + { + outDims[d] = pointDims[d]; + } + } + + VTKM_CONT void operator()(const vtkm::cont::CellSet& cellSet, vtkm::Id3& outDims) const + { + outDims[0] = cellSet.GetNumberOfPoints(); + } +}; + +VTKM_CONT vtkm::Id3 Get3DPointDimensions( + const vtkm::cont::UnknownCellSet& unknownCellSet) +{ + vtkm::Id3 dims(1); + unknownCellSet.CastAndCallForTypes( + Get3DPointDimensionsFunctor{}, dims); + return dims; +} +//// +//// END-EXAMPLE UnknownCellSetCastAndCallForTypes +//// + +VTKM_CONT vtkm::Id3 Get3DStructuredPointDimensions( + const vtkm::cont::UnknownCellSet& unknownCellSet) +{ + vtkm::Id3 dims; + //// + //// BEGIN-EXAMPLE UncertainCellSet + //// + using StructuredCellSetList = vtkm::List, + vtkm::cont::CellSetStructured<2>, + vtkm::cont::CellSetStructured<3>>; + vtkm::cont::UncertainCellSet uncertainCellSet(unknownCellSet); + uncertainCellSet.CastAndCall(Get3DPointDimensionsFunctor{}, dims); + //// + //// END-EXAMPLE UncertainCellSet + //// + return dims; +} + +} // namespace cast_and_call_for_types_example + +struct MyWorklet : vtkm::worklet::WorkletVisitCellsWithPoints +{ + using ControlSignature = void(CellSetIn, FieldOutCell); + using ExecutionSignature = _2(IncidentElementCount); + + VTKM_EXEC vtkm::IdComponent operator()(vtkm::IdComponent pointCount) const + { + return pointCount; + } +}; + +void CreateUniformGrid() +{ + std::cout << "Creating uniform grid." << std::endl; + + //// + //// BEGIN-EXAMPLE CreateUniformGrid + //// + vtkm::cont::DataSetBuilderUniform dataSetBuilder; + + vtkm::cont::DataSet dataSet = dataSetBuilder.Create(vtkm::Id3(101, 101, 26)); + //// + //// END-EXAMPLE CreateUniformGrid + //// + + vtkm::Bounds bounds = dataSet.GetCoordinateSystem().GetBounds(); + std::cout << bounds << std::endl; + + VTKM_TEST_ASSERT(test_equal(bounds, vtkm::Bounds(0, 100, 0, 100, 0, 25)), + "Bad bounds"); + vtkm::cont::UnknownCellSet unknownCellSet = dataSet.GetCellSet(); + VTKM_TEST_ASSERT(can_convert_example::Get3DPointDimensions(unknownCellSet) == + vtkm::Id3(101, 101, 26)); + VTKM_TEST_ASSERT(cast_and_call_for_types_example::Get3DPointDimensions( + unknownCellSet) == vtkm::Id3(101, 101, 26)); + VTKM_TEST_ASSERT(cast_and_call_for_types_example::Get3DStructuredPointDimensions( + unknownCellSet) == vtkm::Id3(101, 101, 26)); + + vtkm::cont::ArrayHandle outArray; + //// + //// BEGIN-EXAMPLE UnknownCellSetResetCellSetList + //// + using StructuredCellSetList = vtkm::List, + vtkm::cont::CellSetStructured<2>, + vtkm::cont::CellSetStructured<3>>; + vtkm::cont::Invoker invoke; + invoke( + MyWorklet{}, unknownCellSet.ResetCellSetList(), outArray); + //// + //// END-EXAMPLE UnknownCellSetResetCellSetList + //// +} + +void CreateUniformGridCustomOriginSpacing() +{ + std::cout << "Creating uniform grid with custom origin and spacing." << std::endl; + + //// + //// BEGIN-EXAMPLE CreateUniformGridCustomOriginSpacing + //// + vtkm::cont::DataSetBuilderUniform dataSetBuilder; + + vtkm::cont::DataSet dataSet = dataSetBuilder.Create(vtkm::Id3(101, 101, 26), + vtkm::Vec3f(-50.0, -50.0, -50.0), + vtkm::Vec3f(1.0, 1.0, 4.0)); + //// + //// END-EXAMPLE CreateUniformGridCustomOriginSpacing + //// + + vtkm::Bounds bounds = dataSet.GetCoordinateSystem().GetBounds(); + std::cout << bounds << std::endl; + + VTKM_TEST_ASSERT(test_equal(bounds, vtkm::Bounds(-50, 50, -50, 50, -50, 50)), + "Bad bounds"); +} + +void CreateRectilinearGrid() +{ + std::cout << "Create rectilinear grid." << std::endl; + + //// + //// BEGIN-EXAMPLE CreateRectilinearGrid + //// + // Make x coordinates range from -4 to 4 with tighter spacing near 0. + std::vector xCoordinates; + for (vtkm::Float32 x = -2.0f; x <= 2.0f; x += 0.02f) + { + xCoordinates.push_back(vtkm::CopySign(x * x, x)); + } + + // Make y coordinates range from 0 to 2 with tighter spacing near 2. + std::vector yCoordinates; + for (vtkm::Float32 y = 0.0f; y <= 4.0f; y += 0.02f) + { + yCoordinates.push_back(vtkm::Sqrt(y)); + } + + // Make z coordinates rangefrom -1 to 1 with even spacing. + std::vector zCoordinates; + for (vtkm::Float32 z = -1.0f; z <= 1.0f; z += 0.02f) + { + zCoordinates.push_back(z); + } + + vtkm::cont::DataSetBuilderRectilinear dataSetBuilder; + + vtkm::cont::DataSet dataSet = + dataSetBuilder.Create(xCoordinates, yCoordinates, zCoordinates); + //// + //// END-EXAMPLE CreateRectilinearGrid + //// + + vtkm::Id numPoints = dataSet.GetCellSet().GetNumberOfPoints(); + std::cout << "Num points: " << numPoints << std::endl; + VTKM_TEST_ASSERT(numPoints == 4080501, "Got wrong number of points."); + + vtkm::Bounds bounds = dataSet.GetCoordinateSystem().GetBounds(); + std::cout << bounds << std::endl; + + VTKM_TEST_ASSERT(test_equal(bounds, vtkm::Bounds(-4, 4, 0, 2, -1, 1)), "Bad bounds"); +} + +void CreateExplicitGrid() +{ + std::cout << "Creating explicit grid." << std::endl; + + //// + //// BEGIN-EXAMPLE CreateExplicitGrid + //// + // Array of point coordinates. + std::vector pointCoordinates; + pointCoordinates.push_back(vtkm::Vec3f_32(1.1f, 0.0f, 0.0f)); + pointCoordinates.push_back(vtkm::Vec3f_32(0.2f, 0.4f, 0.0f)); + pointCoordinates.push_back(vtkm::Vec3f_32(0.9f, 0.6f, 0.0f)); + pointCoordinates.push_back(vtkm::Vec3f_32(1.4f, 0.5f, 0.0f)); + pointCoordinates.push_back(vtkm::Vec3f_32(1.8f, 0.3f, 0.0f)); + pointCoordinates.push_back(vtkm::Vec3f_32(0.4f, 1.0f, 0.0f)); + pointCoordinates.push_back(vtkm::Vec3f_32(1.0f, 1.2f, 0.0f)); + pointCoordinates.push_back(vtkm::Vec3f_32(1.5f, 0.9f, 0.0f)); + + // Array of shapes. + std::vector shapes; + shapes.push_back(vtkm::CELL_SHAPE_TRIANGLE); + shapes.push_back(vtkm::CELL_SHAPE_QUAD); + shapes.push_back(vtkm::CELL_SHAPE_TRIANGLE); + shapes.push_back(vtkm::CELL_SHAPE_POLYGON); + shapes.push_back(vtkm::CELL_SHAPE_TRIANGLE); + + // Array of number of indices per cell. + std::vector numIndices; + numIndices.push_back(3); + numIndices.push_back(4); + numIndices.push_back(3); + numIndices.push_back(5); + numIndices.push_back(3); + + // Connectivity array. + std::vector connectivity; + connectivity.push_back(0); // Cell 0 + connectivity.push_back(2); + connectivity.push_back(1); + connectivity.push_back(0); // Cell 1 + connectivity.push_back(4); + connectivity.push_back(3); + connectivity.push_back(2); + connectivity.push_back(1); // Cell 2 + connectivity.push_back(2); + connectivity.push_back(5); + connectivity.push_back(2); // Cell 3 + connectivity.push_back(3); + connectivity.push_back(7); + connectivity.push_back(6); + connectivity.push_back(5); + connectivity.push_back(3); // Cell 4 + connectivity.push_back(4); + connectivity.push_back(7); + + // Copy these arrays into a DataSet. + vtkm::cont::DataSetBuilderExplicit dataSetBuilder; + + vtkm::cont::DataSet dataSet = + dataSetBuilder.Create(pointCoordinates, shapes, numIndices, connectivity); + //// + //// END-EXAMPLE CreateExplicitGrid + //// + + vtkm::cont::CellSetExplicit<> cellSet; + dataSet.GetCellSet().AsCellSet(cellSet); + VTKM_TEST_ASSERT(test_equal(cellSet.GetNumberOfPoints(), 8), + "Data set has wrong number of points."); + VTKM_TEST_ASSERT(test_equal(cellSet.GetNumberOfCells(), 5), + "Data set has wrong number of cells."); + + vtkm::Bounds bounds = dataSet.GetCoordinateSystem().GetBounds(); + std::cout << bounds << std::endl; + + VTKM_TEST_ASSERT(test_equal(bounds, vtkm::Bounds(0.2, 1.8, 0.0, 1.2, 0.0, 0.0)), + "Bad bounds"); + + // Do a simple check of the connectivity by getting the number of cells + // incident on each point. This array is unlikely to be correct if the + // topology got screwed up. + auto numCellsPerPoint = cellSet.GetNumIndicesArray(vtkm::TopologyElementTagPoint(), + vtkm::TopologyElementTagCell()); + + vtkm::cont::printSummary_ArrayHandle(numCellsPerPoint, std::cout); + std::cout << std::endl; + auto numCellsPortal = numCellsPerPoint.ReadPortal(); + VTKM_TEST_ASSERT(test_equal(numCellsPortal.Get(0), 2), + "Wrong number of cells on point 0"); + VTKM_TEST_ASSERT(test_equal(numCellsPortal.Get(1), 2), + "Wrong number of cells on point 1"); + VTKM_TEST_ASSERT(test_equal(numCellsPortal.Get(2), 4), + "Wrong number of cells on point 2"); + VTKM_TEST_ASSERT(test_equal(numCellsPortal.Get(3), 3), + "Wrong number of cells on point 3"); + VTKM_TEST_ASSERT(test_equal(numCellsPortal.Get(4), 2), + "Wrong number of cells on point 4"); + VTKM_TEST_ASSERT(test_equal(numCellsPortal.Get(5), 2), + "Wrong number of cells on point 5"); + VTKM_TEST_ASSERT(test_equal(numCellsPortal.Get(6), 1), + "Wrong number of cells on point 6"); + VTKM_TEST_ASSERT(test_equal(numCellsPortal.Get(7), 2), + "Wrong number of cells on point 7"); +} + +void CreateExplicitGridIterative() +{ + std::cout << "Creating explicit grid iteratively." << std::endl; + + //// + //// BEGIN-EXAMPLE CreateExplicitGridIterative + //// + vtkm::cont::DataSetBuilderExplicitIterative dataSetBuilder; + + dataSetBuilder.AddPoint(1.1, 0.0, 0.0); + dataSetBuilder.AddPoint(0.2, 0.4, 0.0); + dataSetBuilder.AddPoint(0.9, 0.6, 0.0); + dataSetBuilder.AddPoint(1.4, 0.5, 0.0); + dataSetBuilder.AddPoint(1.8, 0.3, 0.0); + dataSetBuilder.AddPoint(0.4, 1.0, 0.0); + dataSetBuilder.AddPoint(1.0, 1.2, 0.0); + dataSetBuilder.AddPoint(1.5, 0.9, 0.0); + + dataSetBuilder.AddCell(vtkm::CELL_SHAPE_TRIANGLE); + dataSetBuilder.AddCellPoint(0); + dataSetBuilder.AddCellPoint(2); + dataSetBuilder.AddCellPoint(1); + + dataSetBuilder.AddCell(vtkm::CELL_SHAPE_QUAD); + dataSetBuilder.AddCellPoint(0); + dataSetBuilder.AddCellPoint(4); + dataSetBuilder.AddCellPoint(3); + dataSetBuilder.AddCellPoint(2); + + dataSetBuilder.AddCell(vtkm::CELL_SHAPE_TRIANGLE); + dataSetBuilder.AddCellPoint(1); + dataSetBuilder.AddCellPoint(2); + dataSetBuilder.AddCellPoint(5); + + dataSetBuilder.AddCell(vtkm::CELL_SHAPE_POLYGON); + dataSetBuilder.AddCellPoint(2); + dataSetBuilder.AddCellPoint(3); + dataSetBuilder.AddCellPoint(7); + dataSetBuilder.AddCellPoint(6); + dataSetBuilder.AddCellPoint(5); + + dataSetBuilder.AddCell(vtkm::CELL_SHAPE_TRIANGLE); + dataSetBuilder.AddCellPoint(3); + dataSetBuilder.AddCellPoint(4); + dataSetBuilder.AddCellPoint(7); + + vtkm::cont::DataSet dataSet = dataSetBuilder.Create(); + //// + //// END-EXAMPLE CreateExplicitGridIterative + //// + + vtkm::cont::UnknownCellSet unknownCells = dataSet.GetCellSet(); + + //// + //// BEGIN-EXAMPLE UnknownCellSetAsCellSet + //// + vtkm::cont::CellSetExplicit<> cellSet; + unknownCells.AsCellSet(cellSet); + + // This is an equivalent way to get the cell set. + auto cellSet2 = unknownCells.AsCellSet>(); + //// + //// END-EXAMPLE UnknownCellSetAsCellSet + //// + + VTKM_STATIC_ASSERT((std::is_same::value)); + VTKM_TEST_ASSERT(cellSet.GetConnectivityArray(vtkm::TopologyElementTagCell{}, + vtkm::TopologyElementTagPoint{}) == + cellSet2.GetConnectivityArray(vtkm::TopologyElementTagCell{}, + vtkm::TopologyElementTagPoint{})); + + VTKM_TEST_ASSERT(test_equal(cellSet.GetNumberOfPoints(), 8), + "Data set has wrong number of points."); + VTKM_TEST_ASSERT(test_equal(cellSet.GetNumberOfCells(), 5), + "Data set has wrong number of cells."); + + vtkm::Bounds bounds = dataSet.GetCoordinateSystem().GetBounds(); + std::cout << bounds << std::endl; + + VTKM_TEST_ASSERT(test_equal(bounds, vtkm::Bounds(0.2, 1.8, 0.0, 1.2, 0.0, 0.0)), + "Bad bounds"); + + // Do a simple check of the connectivity by getting the number of cells + // incident on each point. This array is unlikely to be correct if the + // topology got screwed up. + auto numCellsPerPoint = cellSet.GetNumIndicesArray(vtkm::TopologyElementTagPoint(), + vtkm::TopologyElementTagCell()); + + vtkm::cont::printSummary_ArrayHandle(numCellsPerPoint, std::cout); + std::cout << std::endl; + auto numCellsPortal = numCellsPerPoint.ReadPortal(); + VTKM_TEST_ASSERT(test_equal(numCellsPortal.Get(0), 2), + "Wrong number of cells on point 0"); + VTKM_TEST_ASSERT(test_equal(numCellsPortal.Get(1), 2), + "Wrong number of cells on point 1"); + VTKM_TEST_ASSERT(test_equal(numCellsPortal.Get(2), 4), + "Wrong number of cells on point 2"); + VTKM_TEST_ASSERT(test_equal(numCellsPortal.Get(3), 3), + "Wrong number of cells on point 3"); + VTKM_TEST_ASSERT(test_equal(numCellsPortal.Get(4), 2), + "Wrong number of cells on point 4"); + VTKM_TEST_ASSERT(test_equal(numCellsPortal.Get(5), 2), + "Wrong number of cells on point 5"); + VTKM_TEST_ASSERT(test_equal(numCellsPortal.Get(6), 1), + "Wrong number of cells on point 6"); + VTKM_TEST_ASSERT(test_equal(numCellsPortal.Get(7), 2), + "Wrong number of cells on point 7"); +} + +void AddFieldData() +{ + std::cout << "Add field data." << std::endl; + + //// + //// BEGIN-EXAMPLE AddFieldData + //// + // Make a simple structured data set. + const vtkm::Id3 pointDimensions(20, 20, 10); + const vtkm::Id3 cellDimensions = pointDimensions - vtkm::Id3(1, 1, 1); + vtkm::cont::DataSetBuilderUniform dataSetBuilder; + vtkm::cont::DataSet dataSet = dataSetBuilder.Create(pointDimensions); + + // Create a field that identifies points on the boundary. + std::vector boundaryPoints; + for (vtkm::Id zIndex = 0; zIndex < pointDimensions[2]; zIndex++) + { + for (vtkm::Id yIndex = 0; yIndex < pointDimensions[1]; yIndex++) + { + for (vtkm::Id xIndex = 0; xIndex < pointDimensions[0]; xIndex++) + { + if ((xIndex == 0) || (xIndex == pointDimensions[0] - 1) || (yIndex == 0) || + (yIndex == pointDimensions[1] - 1) || (zIndex == 0) || + (zIndex == pointDimensions[2] - 1)) + { + boundaryPoints.push_back(1); + } + else + { + boundaryPoints.push_back(0); + } + } + } + } + + dataSet.AddPointField("boundary_points", boundaryPoints); + + // Create a field that identifies cells on the boundary. + std::vector boundaryCells; + for (vtkm::Id zIndex = 0; zIndex < cellDimensions[2]; zIndex++) + { + for (vtkm::Id yIndex = 0; yIndex < cellDimensions[1]; yIndex++) + { + for (vtkm::Id xIndex = 0; xIndex < cellDimensions[0]; xIndex++) + { + if ((xIndex == 0) || (xIndex == cellDimensions[0] - 1) || (yIndex == 0) || + (yIndex == cellDimensions[1] - 1) || (zIndex == 0) || + (zIndex == cellDimensions[2] - 1)) + { + boundaryCells.push_back(1); + } + else + { + boundaryCells.push_back(0); + } + } + } + } + + dataSet.AddCellField("boundary_cells", boundaryCells); + //// + //// END-EXAMPLE AddFieldData + //// +} + +void CreateCellSetPermutation() +{ + std::cout << "Create a cell set permutation" << std::endl; + + //// + //// BEGIN-EXAMPLE CreateCellSetPermutation + //// + // Create a simple data set. + vtkm::cont::DataSetBuilderUniform dataSetBuilder; + vtkm::cont::DataSet originalDataSet = dataSetBuilder.Create(vtkm::Id3(33, 33, 26)); + vtkm::cont::CellSetStructured<3> originalCellSet; + originalDataSet.GetCellSet().AsCellSet(originalCellSet); + + // Create a permutation array for the cells. Each value in the array refers + // to a cell in the original cell set. This particular array selects every + // 10th cell. + vtkm::cont::ArrayHandleCounting permutationArray(0, 10, 2560); + + // Create a permutation of that cell set containing only every 10th cell. + vtkm::cont::CellSetPermutation, + vtkm::cont::ArrayHandleCounting> + permutedCellSet(permutationArray, originalCellSet); + //// + //// END-EXAMPLE CreateCellSetPermutation + //// + + std::cout << "Num points: " << permutedCellSet.GetNumberOfPoints() << std::endl; + VTKM_TEST_ASSERT(permutedCellSet.GetNumberOfPoints() == 28314, + "Wrong number of points."); + std::cout << "Num cells: " << permutedCellSet.GetNumberOfCells() << std::endl; + VTKM_TEST_ASSERT(permutedCellSet.GetNumberOfCells() == 2560, "Wrong number of cells."); +} + +void CreatePartitionedDataSet() +{ + std::cout << "Creating partitioned data." << std::endl; + + //// + //// BEGIN-EXAMPLE CreatePartitionedDataSet + //// + // Create two uniform data sets + vtkm::cont::DataSetBuilderUniform dataSetBuilder; + + vtkm::cont::DataSet dataSet1 = dataSetBuilder.Create(vtkm::Id3(10, 10, 10)); + vtkm::cont::DataSet dataSet2 = dataSetBuilder.Create(vtkm::Id3(30, 30, 30)); + + // Add the datasets to a multi block + vtkm::cont::PartitionedDataSet partitionedData; + partitionedData.AppendPartitions({ dataSet1, dataSet2 }); + //// + //// END-EXAMPLE CreatePartitionedDataSet + //// + + VTKM_TEST_ASSERT(partitionedData.GetNumberOfPartitions() == 2, + "Incorrect number of blocks"); +} + +void QueryPartitionedDataSet() +{ + std::cout << "Query on a partitioned data." << std::endl; + + vtkm::cont::testing::MakeTestDataSet makeData; + + vtkm::cont::PartitionedDataSet partitionedData; + partitionedData.AppendPartitions( + { makeData.Make2DExplicitDataSet0(), makeData.Make3DExplicitDataSet5() }); + + //// + //// BEGIN-EXAMPLE QueryPartitionedDataSet + //// + // Get the bounds of a multi-block data set + vtkm::Bounds bounds = vtkm::cont::BoundsCompute(partitionedData); + + // Get the overall min/max of a field named "cellvar" + vtkm::cont::ArrayHandle cellvarRanges = + vtkm::cont::FieldRangeCompute(partitionedData, "cellvar"); + + // Assuming the "cellvar" field has scalar values, then cellvarRanges has one entry + vtkm::Range cellvarRange = cellvarRanges.ReadPortal().Get(0); + //// + //// END-EXAMPLE QueryPartitionedDataSet + //// + + std::cout << bounds << std::endl; + VTKM_TEST_ASSERT(test_equal(bounds, vtkm::Bounds(0.0, 3.0, 0.0, 4.0, 0.0, 1.0)), + "Bad bounds"); + + std::cout << cellvarRange << std::endl; + VTKM_TEST_ASSERT(test_equal(cellvarRange, vtkm::Range(0, 130.5)), "Bad range"); +} + +void FilterPartitionedDataSet() +{ + std::cout << "Filter on a partitioned data." << std::endl; + + vtkm::cont::testing::MakeTestDataSet makeData; + + vtkm::cont::PartitionedDataSet partitionedData; + partitionedData.AppendPartitions( + { makeData.Make3DUniformDataSet0(), makeData.Make3DUniformDataSet1() }); + + //// + //// BEGIN-EXAMPLE FilterPartitionedDataSet + //// + vtkm::filter::field_conversion::CellAverage cellAverage; + cellAverage.SetActiveField("pointvar", vtkm::cont::Field::Association::Points); + + vtkm::cont::PartitionedDataSet results = cellAverage.Execute(partitionedData); + //// + //// END-EXAMPLE FilterPartitionedDataSet + //// + + VTKM_TEST_ASSERT(results.GetNumberOfPartitions() == 2, "Incorrect number of blocks."); +} + +void Test() +{ + CreateUniformGrid(); + CreateUniformGridCustomOriginSpacing(); + CreateRectilinearGrid(); + CreateExplicitGrid(); + CreateExplicitGridIterative(); + AddFieldData(); + CreateCellSetPermutation(); + CreatePartitionedDataSet(); + QueryPartitionedDataSet(); + FilterPartitionedDataSet(); +} + +} // namespace DataSetCreationNamespace + +int GuideExampleDataSetCreation(int argc, char* argv[]) +{ + return vtkm::cont::testing::Testing::Run(DataSetCreationNamespace::Test, argc, argv); +} diff --git a/docs/users-guide/examples/GuideExampleErrorHandling.cxx b/docs/users-guide/examples/GuideExampleErrorHandling.cxx new file mode 100644 index 000000000..24c99734c --- /dev/null +++ b/docs/users-guide/examples/GuideExampleErrorHandling.cxx @@ -0,0 +1,176 @@ +//============================================================================ +// Copyright (c) Kitware, Inc. +// All rights reserved. +// See LICENSE.txt 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 +#include +#include + +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include + +namespace ErrorHandlingNamespace +{ + +//// +//// BEGIN-EXAMPLE CatchingErrors +//// +int main(int argc, char** argv) +{ + //// PAUSE-EXAMPLE + // Suppress unused argument warnings + (void)argv; + //// RESUME-EXAMPLE + try + { + // Do something cool with VTK-m + // ... + //// PAUSE-EXAMPLE + if (argc == 0) + throw vtkm::cont::ErrorBadValue("Oh, no!"); + //// RESUME-EXAMPLE + } + catch (const vtkm::cont::Error& error) + { + std::cout << error.GetMessage() << std::endl; + return 1; + } + return 0; +} +//// +//// END-EXAMPLE CatchingErrors +//// + +//// +//// BEGIN-EXAMPLE Assert +//// +template +VTKM_CONT T GetArrayValue(vtkm::cont::ArrayHandle arrayHandle, vtkm::Id index) +{ + VTKM_ASSERT(index >= 0); + VTKM_ASSERT(index < arrayHandle.GetNumberOfValues()); + //// + //// END-EXAMPLE Assert + //// + return arrayHandle.ReadPortal().Get(index); +} + +VTKM_CONT +void TryGetArrayValue() +{ + GetArrayValue(vtkm::cont::make_ArrayHandle({ 2.0, 5.0 }), 0); + GetArrayValue(vtkm::cont::make_ArrayHandle({ 2.0, 5.0 }), 1); +} + +//// +//// BEGIN-EXAMPLE StaticAssert +//// +template +VTKM_EXEC_CONT void MyMathFunction(T& value) +{ + VTKM_STATIC_ASSERT((std::is_same::DimensionalityTag, + vtkm::TypeTraitsScalarTag>::value)); + + VTKM_STATIC_ASSERT_MSG(sizeof(T) >= 4, + "MyMathFunction needs types with at least 32 bits."); + //// + //// END-EXAMPLE StaticAssert + //// + for (vtkm::IdComponent iteration = 0; iteration < 5; iteration++) + { + value = value * value; + } +} + +VTKM_EXEC_CONT +void TryMyMathFunction() +{ + vtkm::Id value(4); + MyMathFunction(value); +} + +//// +//// BEGIN-EXAMPLE ExecutionErrors +//// +struct SquareRoot : vtkm::worklet::WorkletMapField +{ +public: + using ControlSignature = void(FieldIn, FieldOut); + using ExecutionSignature = _2(_1); + + template + VTKM_EXEC T operator()(T x) const + { + if (x < 0) + { + this->RaiseError("Cannot take the square root of a negative number."); + return vtkm::Nan(); + } + return vtkm::Sqrt(x); + } +}; +//// +//// END-EXAMPLE ExecutionErrors +//// + +VTKM_CONT +void TrySquareRoot() +{ + vtkm::cont::ArrayHandle output; + + vtkm::worklet::DispatcherMapField dispatcher; + + std::cout << "Trying valid input." << std::endl; + vtkm::cont::ArrayHandleCounting validInput(0.0f, 1.0f, 10); + dispatcher.Invoke(validInput, output); + + std::cout << "Trying invalid input." << std::endl; + vtkm::cont::ArrayHandleCounting invalidInput(-2.0, 1.0f, 10); + bool errorCaught = false; + try + { + dispatcher.Invoke(invalidInput, output); + // Some device adapters are launched asynchronously, and you won't get the error + // until a follow-up call. + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + dispatcher.Invoke(invalidInput, output); + } + catch (const vtkm::cont::ErrorExecution& error) + { + std::cout << "Caught this error:" << std::endl; + std::cout << error.GetMessage() << std::endl; + errorCaught = true; + } + VTKM_TEST_ASSERT(errorCaught, "Did not get expected error."); +} + +void Test() +{ + VTKM_TEST_ASSERT(ErrorHandlingNamespace::main(0, NULL) != 0, "No error?"); + TryGetArrayValue(); + TryMyMathFunction(); + TrySquareRoot(); +} + +} // namespace ErrorHandlingNamespace + +int GuideExampleErrorHandling(int argc, char* argv[]) +{ + return vtkm::cont::testing::Testing::Run(ErrorHandlingNamespace::Test, argc, argv); +} diff --git a/docs/users-guide/examples/GuideExampleIO.cxx b/docs/users-guide/examples/GuideExampleIO.cxx new file mode 100644 index 000000000..d8d0a587c --- /dev/null +++ b/docs/users-guide/examples/GuideExampleIO.cxx @@ -0,0 +1,161 @@ +//============================================================================ +// Copyright (c) Kitware, Inc. +// All rights reserved. +// See LICENSE.txt 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. +//============================================================================ + +//// +//// BEGIN-EXAMPLE VTKDataSetWriter +//// +#include + +void SaveDataAsVTKFile(vtkm::cont::DataSet data) +{ + vtkm::io::VTKDataSetWriter writer("data.vtk"); + + writer.WriteDataSet(data); +} +//// +//// END-EXAMPLE VTKDataSetWriter +//// + +//// +//// BEGIN-EXAMPLE VTKDataSetReader +//// +#include + +vtkm::cont::DataSet OpenDataFromVTKFile() +{ + vtkm::io::VTKDataSetReader reader("data.vtk"); + + return reader.ReadDataSet(); +} +//// +//// END-EXAMPLE VTKDataSetReader +//// + +//// +//// BEGIN-EXAMPLE ImageReaderPNG +//// +#include + +vtkm::cont::DataSet OpenDataFromPNG() +{ + vtkm::io::ImageReaderPNG imageReader("data.png"); + imageReader.SetPointFieldName("pixel_colors"); + return imageReader.ReadDataSet(); +} +//// +//// END-EXAMPLE ImageReaderPNG +//// + +//// +//// BEGIN-EXAMPLE ImageReaderPNM +//// +#include + +vtkm::cont::DataSet OpenDataFromPNM() +{ + vtkm::io::ImageReaderPNM imageReader("data.ppm"); + imageReader.SetPointFieldName("pixels"); + return imageReader.ReadDataSet(); +} +//// +//// END-EXAMPLE ImageReaderPNM +//// + +//// +//// BEGIN-EXAMPLE ImageWriterPNG +//// +#include + +void WriteToPNG(const vtkm::cont::DataSet& dataSet) +{ + vtkm::io::ImageWriterPNG imageWriter("data.png"); + imageWriter.SetPixelDepth(vtkm::io::ImageWriterPNG::PixelDepth::PIXEL_16); + imageWriter.WriteDataSet(dataSet); +} +//// +//// END-EXAMPLE ImageWriterPNG +//// + +//// +//// BEGIN-EXAMPLE ImageWriterPNM +//// +#include + +void WriteToPNM(const vtkm::cont::DataSet& dataSet) +{ + vtkm::io::ImageWriterPNM imageWriter("data.ppm"); + imageWriter.SetPixelDepth(vtkm::io::ImageWriterPNM::PixelDepth::PIXEL_16); + imageWriter.WriteDataSet(dataSet); +} +//// +//// END-EXAMPLE ImageWriterPNM +//// + +#include +#include +#include +#include + +namespace +{ + +void TestIO() +{ + std::cout << "Writing data" << std::endl; + vtkm::cont::testing::MakeTestDataSet makeDataSet; + vtkm::cont::DataSet createdData = makeDataSet.Make3DExplicitDataSetCowNose(); + SaveDataAsVTKFile(createdData); + + std::cout << "Reading data" << std::endl; + vtkm::cont::DataSet readData = OpenDataFromVTKFile(); + + const vtkm::cont::CellSet* createdCellSet = createdData.GetCellSet().GetCellSetBase(); + const vtkm::cont::CellSet* readCellSet = readData.GetCellSet().GetCellSetBase(); + VTKM_TEST_ASSERT(createdCellSet->GetNumberOfCells() == readCellSet->GetNumberOfCells(), + "Createded and read data do not match."); + VTKM_TEST_ASSERT(createdCellSet->GetNumberOfPoints() == + readCellSet->GetNumberOfPoints(), + "Createded and read data do not match."); + + std::cout << "Reading and writing image data" << std::endl; + vtkm::Bounds colorBarBounds(-0.8, -0.6, -0.8, 0.8, 0, 0); + vtkm::rendering::Canvas canvas(64, 64); + canvas.SetBackgroundColor(vtkm::rendering::Color::blue); + canvas.Clear(); + canvas.AddColorBar(colorBarBounds, vtkm::cont::ColorTable("inferno"), false); + canvas.BlendBackground(); + vtkm::cont::DataSet imageSource = canvas.GetDataSet("color", nullptr); + + WriteToPNG(imageSource); + WriteToPNM(imageSource); + + using CheckType = typename vtkm::cont::ArrayHandle; + + readData = OpenDataFromPNG(); + VTKM_TEST_ASSERT(readData.HasPointField("pixel_colors"), + "Point Field Not Found: pixel-data"); + vtkm::cont::Field colorField = readData.GetPointField("pixel_colors"); + VTKM_TEST_ASSERT(colorField.GetNumberOfValues() == 64 * 64, "wrong image dimensions"); + VTKM_TEST_ASSERT(colorField.GetData().IsType(), "wrong ArrayHandle type"); + + readData = OpenDataFromPNM(); + VTKM_TEST_ASSERT(readData.HasPointField("pixels"), + "Point Field Not Found: pixel-data"); + colorField = readData.GetPointField("pixels"); + VTKM_TEST_ASSERT(colorField.GetNumberOfValues() == 64 * 64, "wrong image dimensions"); + VTKM_TEST_ASSERT(colorField.GetData().IsType(), "wrong ArrayHandle type"); +} + +} // namespace + +int GuideExampleIO(int argc, char* argv[]) +{ + return vtkm::cont::testing::Testing::Run(TestIO, argc, argv); +} diff --git a/docs/users-guide/examples/GuideExampleInitialization.cxx b/docs/users-guide/examples/GuideExampleInitialization.cxx new file mode 100644 index 000000000..aecf26f5d --- /dev/null +++ b/docs/users-guide/examples/GuideExampleInitialization.cxx @@ -0,0 +1,211 @@ +//============================================================================ +// Copyright (c) Kitware, Inc. +// All rights reserved. +// See LICENSE.txt 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. +//============================================================================ + +//// +//// BEGIN-EXAMPLE BasicInitialize +//// +#include +//// PAUSE-EXAMPLE +#include +#include +#include + +namespace +{ + +namespace InitExample +{ + +//// RESUME-EXAMPLE + +int main(int argc, char** argv) +{ + vtkm::cont::InitializeOptions options = + vtkm::cont::InitializeOptions::ErrorOnBadOption | + vtkm::cont::InitializeOptions::DefaultAnyDevice; + vtkm::cont::InitializeResult config = vtkm::cont::Initialize(argc, argv, options); + + if (argc != 2) + { + std::cerr << "USAGE: " << argv[0] << " [options] filename" << std::endl; + std::cerr << "Available options are:" << std::endl; + std::cerr << config.Usage << std::endl; + return 1; + } + std::string filename = argv[1]; + + // Do something cool with VTK-m + // ... + + return 0; +} +//// +//// END-EXAMPLE BasicInitialize +//// + +} // namespace InitExample + +namespace LoggingExample +{ + +//// +//// BEGIN-EXAMPLE InitializeLogging +//// +static const vtkm::cont::LogLevel CustomLogLevel = vtkm::cont::LogLevel::UserFirst; + +int main(int argc, char** argv) +{ + vtkm::cont::SetLogLevelName(CustomLogLevel, "custom"); + + // For this example we will set the log level manually. + // The user can override this with the --vtkm-log-level command line flag. + vtkm::cont::SetStderrLogLevel(CustomLogLevel); + + vtkm::cont::Initialize(argc, argv); + + // Do interesting stuff... + //// + //// END-EXAMPLE InitializeLogging + //// + + return 0; +} + +//// +//// BEGIN-EXAMPLE ScopedFunctionLogging +//// +void TestFunc() +{ + VTKM_LOG_SCOPE_FUNCTION(vtkm::cont::LogLevel::Info); + VTKM_LOG_S(vtkm::cont::LogLevel::Info, "Showcasing function logging"); +} +//// +//// END-EXAMPLE ScopedFunctionLogging +//// + +//// +//// BEGIN-EXAMPLE HelperLogFunctions +//// +template +void DoSomething(T&& x) +{ + VTKM_LOG_S(CustomLogLevel, + "Doing something with type " << vtkm::cont::TypeToString()); + + vtkm::Id arraySize = 100000 * sizeof(T); + VTKM_LOG_S(CustomLogLevel, + "Size of array is " << vtkm::cont::GetHumanReadableSize(arraySize)); + VTKM_LOG_S(CustomLogLevel, + "More precisely it is " << vtkm::cont::GetSizeString(arraySize, 4)); + + VTKM_LOG_S(CustomLogLevel, "Stack location: " << vtkm::cont::GetStackTrace()); + //// + //// END-EXAMPLE HelperLogFunctions + //// + + (void)x; +} + +void ExampleLogging() +{ + //// + //// BEGIN-EXAMPLE BasicLogging + //// + VTKM_LOG_F(vtkm::cont::LogLevel::Info, + "Base VTK-m version: %d.%d", + VTKM_VERSION_MAJOR, + VTKM_VERSION_MINOR); + VTKM_LOG_S(vtkm::cont::LogLevel::Info, "Full VTK-m version: " << VTKM_VERSION_FULL); + //// + //// END-EXAMPLE BasicLogging + //// + + //// + //// BEGIN-EXAMPLE ConditionalLogging + //// + for (size_t i = 0; i < 5; i++) + { + VTKM_LOG_IF_S(vtkm::cont::LogLevel::Info, i % 2 == 0, "Found an even number: " << i); + } + //// + //// END-EXAMPLE ConditionalLogging + //// + + constexpr vtkm::IdComponent numTrials = 3; + + //// + //// BEGIN-EXAMPLE ScopedLogging + //// + for (vtkm::IdComponent trial = 0; trial < numTrials; ++trial) + { + VTKM_LOG_SCOPE(CustomLogLevel, "Trial %d", trial); + + VTKM_LOG_F(CustomLogLevel, "Do thing 1"); + + VTKM_LOG_F(CustomLogLevel, "Do thing 2"); + + //... + } + //// + //// END-EXAMPLE ScopedLogging + //// + + TestFunc(); + + DoSomething(vtkm::Vec{}); + +#if 0 + Error context was removed in VTK-m 2.0 (and was disabled long before then) + // + // BEGIN-EXAMPLE LoggingErrorContext + // + // This message is only logged if a crash occurs + VTKM_LOG_ERROR_CONTEXT("Some variable value", 42); + // + // END-EXAMPLE LoggingErrorContext + // + std::cerr << vtkm::cont::GetLogErrorContext() << "\n"; +#endif +} +} // namespace LoggingExample + +void Test(int argc, char** argv) +{ + LoggingExample::main(argc, argv); + LoggingExample::ExampleLogging(); + + std::string arg0 = "command-name"; + std::string arg1 = "--vtkm-device=any"; + std::string arg2 = "filename"; + std::vector fakeArgv; + fakeArgv.push_back(const_cast(arg0.c_str())); + fakeArgv.push_back(const_cast(arg1.c_str())); + fakeArgv.push_back(const_cast(arg2.c_str())); + InitExample::main(3, &fakeArgv.front()); +} + +} // anonymous namespace + +int GuideExampleInitialization(int argc, char* argv[]) +{ + // Do not use standard testing run because that also calls Initialize + // and will foul up the other calls. + try + { + Test(argc, argv); + } + catch (...) + { + std::cerr << "Uncaught exception" << std::endl; + return 1; + } + + return 0; +} diff --git a/docs/users-guide/examples/GuideExampleProvidedFilters.cxx b/docs/users-guide/examples/GuideExampleProvidedFilters.cxx new file mode 100644 index 000000000..d301982b7 --- /dev/null +++ b/docs/users-guide/examples/GuideExampleProvidedFilters.cxx @@ -0,0 +1,556 @@ +//============================================================================ +// Copyright (c) Kitware, Inc. +// All rights reserved. +// See LICENSE.txt 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +namespace +{ + +//// +//// BEGIN-EXAMPLE PointElevation +//// +VTKM_CONT +vtkm::cont::DataSet ComputeAirPressure(vtkm::cont::DataSet dataSet) +{ + //// LABEL Construct + vtkm::filter::field_transform::PointElevation elevationFilter; + + // Use the elevation filter to estimate atmospheric pressure based on the + // height of the point coordinates. Atmospheric pressure is 101325 Pa at + // sea level and drops about 12 Pa per meter. + //// LABEL SetStateStart + elevationFilter.SetLowPoint(0.0, 0.0, 0.0); + elevationFilter.SetHighPoint(0.0, 0.0, 2000.0); + elevationFilter.SetRange(101325.0, 77325.0); + + //// LABEL SetInputField + elevationFilter.SetUseCoordinateSystemAsField(true); + + //// LABEL SetStateEnd + //// LABEL SetOutputField + elevationFilter.SetOutputFieldName("pressure"); + + //// LABEL Execute + vtkm::cont::DataSet result = elevationFilter.Execute(dataSet); + + return result; +} +//// +//// END-EXAMPLE PointElevation +//// + +void DoPointElevation() +{ + std::cout << "** Run elevation filter" << std::endl; + + vtkm::cont::testing::MakeTestDataSet makeData; + vtkm::cont::DataSet inData = makeData.Make3DRegularDataSet0(); + + vtkm::cont::DataSet pressureData = ComputeAirPressure(inData); + + pressureData.GetField("pressure").PrintSummary(std::cout); + std::cout << std::endl; +} + +void DoVertexClustering() +{ + std::cout << "** Run vertex clustering filter" << std::endl; + + vtkm::cont::testing::MakeTestDataSet makeData; + vtkm::cont::DataSet originalSurface = makeData.Make3DExplicitDataSetCowNose(); + + //// + //// BEGIN-EXAMPLE VertexClustering + //// + vtkm::filter::geometry_refinement::VertexClustering vertexClustering; + + vertexClustering.SetNumberOfDivisions(vtkm::Id3(128, 128, 128)); + + vtkm::cont::DataSet simplifiedSurface = vertexClustering.Execute(originalSurface); + //// + //// END-EXAMPLE VertexClustering + //// + + simplifiedSurface.PrintSummary(std::cout); + std::cout << std::endl; +} + +void DoClipWithImplicitFunction() +{ + std::cout << "** Run clip with implicit function filter" << std::endl; + + vtkm::cont::testing::MakeTestDataSet makeData; + vtkm::cont::DataSet inData = makeData.Make3DUniformDataSet0(); + + //// + //// BEGIN-EXAMPLE ClipWithImplicitFunction + //// + //// + //// BEGIN-EXAMPLE ImplicitFunctionGeneral + //// + // Parameters needed for implicit function + vtkm::Sphere implicitFunction(vtkm::make_Vec(1, 0, 1), 0.5); + + // Create an instance of a clip filter with this implicit function. + vtkm::filter::contour::ClipWithImplicitFunction clip; + clip.SetImplicitFunction(implicitFunction); + //// + //// END-EXAMPLE ImplicitFunctionGeneral + //// + + // By default, ClipWithImplicitFunction will remove everything inside the sphere. + // Set the invert clip flag to keep the inside of the sphere and remove everything + // else. + clip.SetInvertClip(true); + + // Execute the clip filter + vtkm::cont::DataSet outData = clip.Execute(inData); + //// + //// END-EXAMPLE ClipWithImplicitFunction + //// + + outData.PrintSummary(std::cout); + std::cout << std::endl; +} + +void DoContour() +{ + std::cout << "** Run Contour filter" << std::endl; + + vtkm::cont::testing::MakeTestDataSet makeData; + vtkm::cont::DataSet inData = makeData.Make3DRectilinearDataSet0(); + + //// + //// BEGIN-EXAMPLE Contour + //// + vtkm::filter::contour::Contour contour; + + contour.SetActiveField("pointvar"); + contour.SetIsoValue(10.0); + + vtkm::cont::DataSet isosurface = contour.Execute(inData); + //// + //// END-EXAMPLE Contour + //// + + isosurface.PrintSummary(std::cout); + std::cout << std::endl; + + vtkm::filter::contour::Contour filter = contour; + //// + //// BEGIN-EXAMPLE SetActiveFieldWithAssociation + //// + filter.SetActiveField("pointvar", vtkm::cont::Field::Association::Points); + //// + //// END-EXAMPLE SetActiveFieldWithAssociation + //// + vtkm::cont::DataSet other = filter.Execute(inData); + VTKM_TEST_ASSERT(isosurface.GetNumberOfCells() == other.GetNumberOfCells()); + VTKM_TEST_ASSERT(isosurface.GetNumberOfPoints() == other.GetNumberOfPoints()); +} + +void DoClipWithField() +{ + std::cout << "** Run clip with field filter" << std::endl; + + vtkm::cont::testing::MakeTestDataSet makeData; + vtkm::cont::DataSet inData = makeData.Make3DUniformDataSet0(); + + //// + //// BEGIN-EXAMPLE ClipWithField + //// + // Create an instance of a clip filter that discards all regions with scalar + // value less than 25. + vtkm::filter::contour::ClipWithField clip; + clip.SetClipValue(25.0); + clip.SetActiveField("pointvar"); + + // Execute the clip filter + vtkm::cont::DataSet outData = clip.Execute(inData); + //// + //// END-EXAMPLE ClipWithField + //// + + outData.PrintSummary(std::cout); + std::cout << std::endl; +} + +void DoStreamlines() +{ + std::cout << "** Run streamlines filter" << std::endl; + + vtkm::cont::DataSetBuilderUniform dataSetBuilder; + + vtkm::cont::DataSet inData = dataSetBuilder.Create(vtkm::Id3(5, 5, 5)); + vtkm::Id numPoints = inData.GetCellSet().GetNumberOfPoints(); + + vtkm::cont::ArrayHandle vectorField; + vtkm::cont::ArrayCopy( + vtkm::cont::make_ArrayHandleConstant(vtkm::Vec3f(1, 0, 0), numPoints), vectorField); + inData.AddPointField("vectorvar", vectorField); + + //// + //// BEGIN-EXAMPLE Streamlines + //// + vtkm::filter::flow::Streamline streamlines; + + // Specify the seeds. + vtkm::cont::ArrayHandle seedArray; + seedArray.Allocate(2); + seedArray.WritePortal().Set(0, vtkm::Particle({ 0, 0, 0 }, 0)); + seedArray.WritePortal().Set(1, vtkm::Particle({ 1, 1, 1 }, 1)); + + streamlines.SetActiveField("vectorvar"); + streamlines.SetStepSize(0.1f); + streamlines.SetNumberOfSteps(100); + streamlines.SetSeeds(seedArray); + + vtkm::cont::DataSet output = streamlines.Execute(inData); + //// + //// END-EXAMPLE Streamlines + //// + + output.PrintSummary(std::cout); + std::cout << std::endl; +} + +void DoStreamsurface() +{ + std::cout << "** Run streamsurface filter" << std::endl; + + vtkm::cont::DataSetBuilderUniform dataSetBuilder; + + vtkm::cont::DataSet inData = dataSetBuilder.Create(vtkm::Id3(5, 5, 5)); + vtkm::Id numPoints = inData.GetCellSet().GetNumberOfPoints(); + + vtkm::cont::ArrayHandle vectorField; + vtkm::cont::ArrayCopy( + vtkm::cont::make_ArrayHandleConstant(vtkm::Vec3f(1, 0, 0), numPoints), vectorField); + inData.AddPointField("vectorvar", vectorField); + + //// + //// BEGIN-EXAMPLE StreamSurface + //// + vtkm::filter::flow::StreamSurface streamSurface; + + // Specify the seeds. + vtkm::cont::ArrayHandle seedArray; + seedArray.Allocate(2); + seedArray.WritePortal().Set(0, vtkm::Particle({ 0, 0, 0 }, 0)); + seedArray.WritePortal().Set(1, vtkm::Particle({ 1, 1, 1 }, 1)); + + streamSurface.SetActiveField("vectorvar"); + streamSurface.SetStepSize(0.1f); + streamSurface.SetNumberOfSteps(100); + streamSurface.SetSeeds(seedArray); + + vtkm::cont::DataSet output = streamSurface.Execute(inData); + //// + //// END-EXAMPLE StreamSurface + //// + + output.PrintSummary(std::cout); + std::cout << std::endl; +} + +void DoTube() +{ + std::cout << "** Run tube filter" << std::endl; + + vtkm::cont::DataSetBuilderExplicitIterative dsb; + std::vector ids; + vtkm::Id pid; + + + pid = dsb.AddPoint(vtkm::Vec3f(1, 0, 0)); + ids.push_back(pid); + pid = dsb.AddPoint(vtkm::Vec3f(2, 1, 0)); + ids.push_back(pid); + pid = dsb.AddPoint(vtkm::Vec3f(3, 0, 0)); + ids.push_back(pid); + dsb.AddCell(vtkm::CELL_SHAPE_POLY_LINE, ids); + + vtkm::cont::DataSet inData = dsb.Create(); + + //// + //// BEGIN-EXAMPLE Tube + //// + vtkm::filter::geometry_refinement::Tube tubeFilter; + + tubeFilter.SetRadius(0.5f); + tubeFilter.SetNumberOfSides(7); + tubeFilter.SetCapping(true); + + vtkm::cont::DataSet output = tubeFilter.Execute(inData); + //// + //// END-EXAMPLE Tube + //// + + output.PrintSummary(std::cout); + std::cout << std::endl; +} + +void DoPathlines() +{ + std::cout << "** Run pathlines filter" << std::endl; + + vtkm::cont::DataSetBuilderUniform dataSetBuilder; + + vtkm::cont::DataSet inData1 = dataSetBuilder.Create(vtkm::Id3(5, 5, 5)); + vtkm::cont::DataSet inData2 = dataSetBuilder.Create(vtkm::Id3(5, 5, 5)); + vtkm::Id numPoints = inData1.GetCellSet().GetNumberOfPoints(); + + vtkm::cont::ArrayHandle vectorField1; + vtkm::cont::ArrayCopy( + vtkm::cont::make_ArrayHandleConstant(vtkm::Vec3f(1, 0, 0), numPoints), vectorField1); + inData1.AddPointField("vectorvar", vectorField1); + + vtkm::cont::ArrayHandle vectorField2; + vtkm::cont::ArrayCopy( + vtkm::cont::make_ArrayHandleConstant(vtkm::Vec3f(0, 1, 0), numPoints), vectorField2); + inData2.AddPointField("vectorvar", vectorField2); + + //// + //// BEGIN-EXAMPLE Pathlines + //// + vtkm::filter::flow::Pathline pathlines; + + // Specify the seeds. + vtkm::cont::ArrayHandle seedArray; + seedArray.Allocate(2); + seedArray.WritePortal().Set(0, vtkm::Particle({ 0, 0, 0 }, 0)); + seedArray.WritePortal().Set(1, vtkm::Particle({ 1, 1, 1 }, 1)); + + pathlines.SetActiveField("vectorvar"); + pathlines.SetStepSize(0.1f); + pathlines.SetNumberOfSteps(100); + pathlines.SetSeeds(seedArray); + pathlines.SetPreviousTime(0.0f); + pathlines.SetNextTime(1.0f); + pathlines.SetNextDataSet(inData2); + + vtkm::cont::DataSet pathlineCurves = pathlines.Execute(inData1); + //// + //// END-EXAMPLE Pathlines + //// + + pathlineCurves.PrintSummary(std::cout); + std::cout << std::endl; +} + +void DoCheckFieldPassing() +{ + std::cout << "** Check field passing" << std::endl; + + vtkm::cont::testing::MakeTestDataSet makeData; + vtkm::cont::DataSet inData = makeData.Make3DRectilinearDataSet0(); + + vtkm::cont::ArrayHandle scalars; + vtkm::cont::ArrayCopy(vtkm::cont::ArrayHandleConstant( + 1, inData.GetCellSet().GetNumberOfPoints()), + scalars); + inData.AddPointField("scalars", scalars); + + vtkm::filter::field_transform::PointElevation filter; + filter.SetLowPoint(0.0, 0.0, 0.0); + filter.SetHighPoint(0.0, 0.0, 1.0); + filter.SetRange(0.0, 1.0); + //// + //// BEGIN-EXAMPLE SetCoordinateSystem + //// + filter.SetUseCoordinateSystemAsField(true); + filter.SetActiveCoordinateSystem(1); + //// + //// END-EXAMPLE SetCoordinateSystem + //// + filter.SetActiveCoordinateSystem(0); + filter.SetOutputFieldName("elevation"); + + { + vtkm::cont::DataSet outData = filter.Execute(inData); + for (vtkm::IdComponent fieldId = 0; fieldId < inData.GetNumberOfFields(); ++fieldId) + { + vtkm::cont::Field inField = inData.GetField(fieldId); + VTKM_TEST_ASSERT(outData.HasField(inField.GetName(), inField.GetAssociation()), + "Did not automatically pass all fields."); + } + } + + { + //// + //// BEGIN-EXAMPLE PassNoFields + //// + filter.SetFieldsToPass(vtkm::filter::FieldSelection::Mode::None); + //// + //// END-EXAMPLE PassNoFields + //// + + //// + //// BEGIN-EXAMPLE PassNoCoordinates + //// + filter.SetPassCoordinateSystems(false); + //// + //// END-EXAMPLE PassNoCoordinates + //// + + vtkm::cont::DataSet outData = filter.Execute(inData); + VTKM_TEST_ASSERT(outData.GetNumberOfFields() == 1, + "Could not turn off passing of fields"); + } + + { + //// + //// BEGIN-EXAMPLE PassOneField + //// + filter.SetFieldsToPass("pointvar"); + //// + //// END-EXAMPLE PassOneField + //// + filter.SetPassCoordinateSystems(false); + + vtkm::cont::DataSet outData = filter.Execute(inData); + outData.PrintSummary(std::cout); + VTKM_TEST_ASSERT(outData.GetNumberOfFields() == 2, + "Could not set field passing correctly."); + VTKM_TEST_ASSERT(outData.HasPointField("pointvar")); + } + + { + //// + //// BEGIN-EXAMPLE PassListOfFields + //// + filter.SetFieldsToPass({ "pointvar", "cellvar" }); + //// + //// END-EXAMPLE PassListOfFields + //// + filter.SetPassCoordinateSystems(false); + + vtkm::cont::DataSet outData = filter.Execute(inData); + outData.PrintSummary(std::cout); + VTKM_TEST_ASSERT(outData.GetNumberOfFields() == 3, + "Could not set field passing correctly."); + VTKM_TEST_ASSERT(outData.HasPointField("pointvar")); + VTKM_TEST_ASSERT(outData.HasCellField("cellvar")); + } + + { + //// + //// BEGIN-EXAMPLE PassExcludeFields + //// + filter.SetFieldsToPass({ "pointvar", "cellvar" }, + vtkm::filter::FieldSelection::Mode::Exclude); + //// + //// END-EXAMPLE PassExcludeFields + //// + + vtkm::cont::DataSet outData = filter.Execute(inData); + outData.PrintSummary(std::cout); + VTKM_TEST_ASSERT(outData.GetNumberOfFields() == (inData.GetNumberOfFields() - 1), + "Could not set field passing correctly."); + VTKM_TEST_ASSERT(outData.HasField("scalars")); + } + + { + //// + //// BEGIN-EXAMPLE FieldSelection + //// + vtkm::filter::FieldSelection fieldSelection; + fieldSelection.AddField("scalars"); + fieldSelection.AddField("cellvar", vtkm::cont::Field::Association::Cells); + + filter.SetFieldsToPass(fieldSelection); + //// + //// END-EXAMPLE FieldSelection + //// + filter.SetPassCoordinateSystems(false); + + vtkm::cont::DataSet outData = filter.Execute(inData); + outData.PrintSummary(std::cout); + VTKM_TEST_ASSERT(outData.GetNumberOfFields() == 3, + "Could not set field passing correctly."); + VTKM_TEST_ASSERT(outData.HasField("scalars")); + VTKM_TEST_ASSERT(outData.HasCellField("cellvar")); + } + + { + //// + //// BEGIN-EXAMPLE PassFieldAndAssociation + //// + filter.SetFieldsToPass("pointvar", vtkm::cont::Field::Association::Points); + //// + //// END-EXAMPLE PassFieldAndAssociation + //// + filter.SetPassCoordinateSystems(false); + + vtkm::cont::DataSet outData = filter.Execute(inData); + outData.PrintSummary(std::cout); + VTKM_TEST_ASSERT(outData.GetNumberOfFields() == 2, + "Could not set field passing correctly."); + VTKM_TEST_ASSERT(outData.HasPointField("pointvar")); + } + + { + //// + //// BEGIN-EXAMPLE PassListOfFieldsAndAssociations + //// + filter.SetFieldsToPass( + { vtkm::make_Pair("pointvar", vtkm::cont::Field::Association::Points), + vtkm::make_Pair("cellvar", vtkm::cont::Field::Association::Cells), + vtkm::make_Pair("scalars", vtkm::cont::Field::Association::Any) }); + //// + //// END-EXAMPLE PassListOfFieldsAndAssociations + //// + filter.SetPassCoordinateSystems(false); + + vtkm::cont::DataSet outData = filter.Execute(inData); + outData.PrintSummary(std::cout); + VTKM_TEST_ASSERT(outData.GetNumberOfFields() == 4, + "Could not set field passing correctly."); + VTKM_TEST_ASSERT(outData.HasPointField("pointvar")); + VTKM_TEST_ASSERT(outData.HasCellField("cellvar")); + VTKM_TEST_ASSERT(outData.HasField("scalars")); + } +} + +void Test() +{ + DoPointElevation(); + DoVertexClustering(); + DoClipWithImplicitFunction(); + DoContour(); + DoClipWithField(); + DoStreamlines(); + DoStreamsurface(); + DoTube(); + DoPathlines(); + DoCheckFieldPassing(); +} + +} // anonymous namespace + +int GuideExampleProvidedFilters(int argc, char* argv[]) +{ + return vtkm::cont::testing::Testing::Run(Test, argc, argv); +} diff --git a/docs/users-guide/examples/GuideExampleRendering.cxx b/docs/users-guide/examples/GuideExampleRendering.cxx new file mode 100644 index 000000000..4decc416f --- /dev/null +++ b/docs/users-guide/examples/GuideExampleRendering.cxx @@ -0,0 +1,214 @@ +//============================================================================ +// Copyright (c) Kitware, Inc. +// All rights reserved. +// See LICENSE.txt 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 + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace +{ + +void DoBasicRender() +{ + // Load some data to render + vtkm::cont::DataSet surfaceData; + try + { + vtkm::io::VTKDataSetReader reader( + vtkm::cont::testing::Testing::GetTestDataBasePath() + "unstructured/cow.vtk"); + surfaceData = reader.ReadDataSet(); + } + catch (vtkm::io::ErrorIO& error) + { + std::cout << "Could not read file:" << std::endl << error.GetMessage() << std::endl; + exit(1); + } + catch (...) + { + throw; + } + + // Initialize VTK-m rendering classes + //// + //// BEGIN-EXAMPLE ConstructView + //// + //// + //// BEGIN-EXAMPLE ActorScene + //// + vtkm::rendering::Actor actor(surfaceData.GetCellSet(), + surfaceData.GetCoordinateSystem(), + surfaceData.GetField("RandomPointScalars")); + + vtkm::rendering::Scene scene; + scene.AddActor(actor); + //// + //// END-EXAMPLE ActorScene + //// + + vtkm::rendering::MapperRayTracer mapper; + //// + //// BEGIN-EXAMPLE Canvas + //// + vtkm::rendering::CanvasRayTracer canvas(1920, 1080); + //// + //// END-EXAMPLE Canvas + //// + + vtkm::rendering::View3D view(scene, mapper, canvas); + //// + //// END-EXAMPLE ConstructView + //// + + //// + //// BEGIN-EXAMPLE ViewColors + //// + view.SetBackgroundColor(vtkm::rendering::Color(1.0f, 1.0f, 1.0f)); + view.SetForegroundColor(vtkm::rendering::Color(0.0f, 0.0f, 0.0f)); + //// + //// END-EXAMPLE ViewColors + //// + + //// + //// BEGIN-EXAMPLE PaintView + //// + view.Paint(); + //// + //// END-EXAMPLE PaintView + //// + + //// + //// BEGIN-EXAMPLE SaveView + //// + view.SaveAs("BasicRendering.png"); + //// + //// END-EXAMPLE SaveView + //// +} + +void DoPointRender() +{ + // Load some data to render + vtkm::cont::DataSet surfaceData; + try + { + vtkm::io::VTKDataSetReader reader( + vtkm::cont::testing::Testing::GetTestDataBasePath() + "unstructured/cow.vtk"); + surfaceData = reader.ReadDataSet(); + } + catch (vtkm::io::ErrorIO& error) + { + std::cout << "Could not read file:" << std::endl << error.GetMessage() << std::endl; + exit(1); + } + catch (...) + { + throw; + } + + // Initialize VTK-m rendering classes + vtkm::rendering::Actor actor(surfaceData.GetCellSet(), + surfaceData.GetCoordinateSystem(), + surfaceData.GetField("RandomPointScalars")); + + vtkm::rendering::Scene scene; + scene.AddActor(actor); + + vtkm::rendering::CanvasRayTracer canvas(1920, 1080); + + //// + //// BEGIN-EXAMPLE MapperGlyphScalar + //// + vtkm::rendering::MapperGlyphScalar mapper; + mapper.SetGlyphType(vtkm::rendering::GlyphType::Cube); + mapper.SetScaleByValue(true); + mapper.SetScaleDelta(10.0f); + + vtkm::rendering::View3D view(scene, mapper, canvas); + //// + //// END-EXAMPLE MapperGlyphScalar + //// + + view.SetBackgroundColor(vtkm::rendering::Color(1.0f, 1.0f, 1.0f)); + view.SetForegroundColor(vtkm::rendering::Color(0.0f, 0.0f, 0.0f)); + + view.Paint(); + + view.SaveAs("GlyphRendering.ppm"); +} + +void DoEdgeRender() +{ + // Load some data to render + vtkm::cont::DataSet surfaceData; + try + { + vtkm::io::VTKDataSetReader reader( + vtkm::cont::testing::Testing::GetTestDataBasePath() + "unstructured/cow.vtk"); + surfaceData = reader.ReadDataSet(); + } + catch (vtkm::io::ErrorIO& error) + { + std::cout << "Could not read file:" << std::endl << error.GetMessage() << std::endl; + exit(1); + } + catch (...) + { + throw; + } + + // Initialize VTK-m rendering classes + vtkm::rendering::Actor actor(surfaceData.GetCellSet(), + surfaceData.GetCoordinateSystem(), + surfaceData.GetField("RandomPointScalars")); + + vtkm::rendering::Scene scene; + scene.AddActor(actor); + + vtkm::rendering::CanvasRayTracer canvas(1920, 1080); + + //// + //// BEGIN-EXAMPLE MapperEdge + //// + vtkm::rendering::MapperWireframer mapper; + vtkm::rendering::View3D view(scene, mapper, canvas); + //// + //// END-EXAMPLE MapperEdge + //// + + view.SetBackgroundColor(vtkm::rendering::Color(1.0f, 1.0f, 1.0f)); + view.SetForegroundColor(vtkm::rendering::Color(0.0f, 0.0f, 0.0f)); + + view.Paint(); + + view.SaveAs("EdgeRendering.png"); +} + +void DoRender() +{ + DoBasicRender(); + DoPointRender(); + DoEdgeRender(); +} + +} // anonymous namespace + +int GuideExampleRendering(int argc, char* argv[]) +{ + return vtkm::cont::testing::Testing::Run(DoRender, argc, argv); +} diff --git a/docs/users-guide/examples/GuideExampleRenderingInteractive.cxx b/docs/users-guide/examples/GuideExampleRenderingInteractive.cxx new file mode 100644 index 000000000..606b00003 --- /dev/null +++ b/docs/users-guide/examples/GuideExampleRenderingInteractive.cxx @@ -0,0 +1,392 @@ +//============================================================================ +// Copyright (c) Kitware, Inc. +// All rights reserved. +// See LICENSE.txt 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. +//============================================================================ + +#ifdef __APPLE__ +// Glut is depricated on apple, but is sticking around for now. Hopefully +// someone will step up and make FreeGlut or OpenGlut compatible. Or perhaps +// we should move to GLFW. For now, just disable the warnings. +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif + +#include + +#include +#include +#include +#include +#include + +#include + +#include + +#ifdef __APPLE__ +#include +#include +#else +#include +#include +#endif + +namespace +{ + +vtkm::rendering::View3D* gViewPointer = NULL; + +int gButtonState[3] = { GLUT_UP, GLUT_UP, GLUT_UP }; +int gMousePositionX; +int gMousePositionY; +bool gNoInteraction; + +void DisplayCallback() +{ + vtkm::rendering::View3D& view = *gViewPointer; + + //// + //// BEGIN-EXAMPLE RenderToOpenGL + //// + view.Paint(); + + // Get the color buffer containing the rendered image. + vtkm::cont::ArrayHandle colorBuffer = + view.GetCanvas().GetColorBuffer(); + + // Pull the C array out of the arrayhandle. + const void* colorArray = + vtkm::cont::ArrayHandleBasic(colorBuffer).GetReadPointer(); + + // Write the C array to an OpenGL buffer. + glDrawPixels((GLint)view.GetCanvas().GetWidth(), + (GLint)view.GetCanvas().GetHeight(), + GL_RGBA, + GL_FLOAT, + colorArray); + + // Swap the OpenGL buffers (system dependent). + //// + //// END-EXAMPLE RenderToOpenGL + //// + glutSwapBuffers(); + if (gNoInteraction) + { + delete gViewPointer; + gViewPointer = NULL; + exit(0); + } +} + +void WindowReshapeCallback(int width, int height) +{ + gViewPointer->GetCanvas().ResizeBuffers(width, height); +} + +void MouseButtonCallback(int buttonIndex, int state, int x, int y) +{ + gButtonState[buttonIndex] = state; + gMousePositionX = x; + gMousePositionY = y; +} + +//// +//// BEGIN-EXAMPLE MouseRotate +//// +void DoMouseRotate(vtkm::rendering::View& view, + vtkm::Id mouseStartX, + vtkm::Id mouseStartY, + vtkm::Id mouseEndX, + vtkm::Id mouseEndY) +{ + vtkm::Id screenWidth = view.GetCanvas().GetWidth(); + vtkm::Id screenHeight = view.GetCanvas().GetHeight(); + + // Convert the mouse position coordinates, given in pixels from 0 to + // width/height, to normalized screen coordinates from -1 to 1. Note that y + // screen coordinates are usually given from the top down whereas our + // geometry transforms are given from bottom up, so you have to reverse the y + // coordiantes. + vtkm::Float32 startX = (2.0f * mouseStartX) / screenWidth - 1.0f; + vtkm::Float32 startY = -((2.0f * mouseStartY) / screenHeight - 1.0f); + vtkm::Float32 endX = (2.0f * mouseEndX) / screenWidth - 1.0f; + vtkm::Float32 endY = -((2.0f * mouseEndY) / screenHeight - 1.0f); + + view.GetCamera().TrackballRotate(startX, startY, endX, endY); +} +//// +//// END-EXAMPLE MouseRotate +//// + +//// +//// BEGIN-EXAMPLE MousePan +//// +void DoMousePan(vtkm::rendering::View& view, + vtkm::Id mouseStartX, + vtkm::Id mouseStartY, + vtkm::Id mouseEndX, + vtkm::Id mouseEndY) +{ + vtkm::Id screenWidth = view.GetCanvas().GetWidth(); + vtkm::Id screenHeight = view.GetCanvas().GetHeight(); + + // Convert the mouse position coordinates, given in pixels from 0 to + // width/height, to normalized screen coordinates from -1 to 1. Note that y + // screen coordinates are usually given from the top down whereas our + // geometry transforms are given from bottom up, so you have to reverse the y + // coordiantes. + vtkm::Float32 startX = (2.0f * mouseStartX) / screenWidth - 1.0f; + vtkm::Float32 startY = -((2.0f * mouseStartY) / screenHeight - 1.0f); + vtkm::Float32 endX = (2.0f * mouseEndX) / screenWidth - 1.0f; + vtkm::Float32 endY = -((2.0f * mouseEndY) / screenHeight - 1.0f); + + vtkm::Float32 deltaX = endX - startX; + vtkm::Float32 deltaY = endY - startY; + + //// + //// BEGIN-EXAMPLE Pan + //// + view.GetCamera().Pan(deltaX, deltaY); + //// + //// END-EXAMPLE Pan + //// +} +//// +//// END-EXAMPLE MousePan +//// + +//// +//// BEGIN-EXAMPLE MouseZoom +//// +void DoMouseZoom(vtkm::rendering::View& view, vtkm::Id mouseStartY, vtkm::Id mouseEndY) +{ + vtkm::Id screenHeight = view.GetCanvas().GetHeight(); + + // Convert the mouse position coordinates, given in pixels from 0 to height, + // to normalized screen coordinates from -1 to 1. Note that y screen + // coordinates are usually given from the top down whereas our geometry + // transforms are given from bottom up, so you have to reverse the y + // coordiantes. + vtkm::Float32 startY = -((2.0f * mouseStartY) / screenHeight - 1.0f); + vtkm::Float32 endY = -((2.0f * mouseEndY) / screenHeight - 1.0f); + + vtkm::Float32 zoomFactor = endY - startY; + + //// + //// BEGIN-EXAMPLE Zoom + //// + view.GetCamera().Zoom(zoomFactor); + //// + //// END-EXAMPLE Zoom + //// +} +//// +//// END-EXAMPLE MouseZoom +//// + +void MouseMoveCallback(int x, int y) +{ + if (gButtonState[0] == GLUT_DOWN) + { + DoMouseRotate(*gViewPointer, gMousePositionX, gMousePositionY, x, y); + } + else if (gButtonState[1] == GLUT_DOWN) + { + DoMousePan(*gViewPointer, gMousePositionX, gMousePositionY, x, y); + } + else if (gButtonState[2] == GLUT_DOWN) + { + DoMouseZoom(*gViewPointer, gMousePositionY, y); + } + + gMousePositionX = x; + gMousePositionY = y; + + glutPostRedisplay(); +} + +void SaveImage() +{ + std::cout << "Saving image." << std::endl; + + vtkm::rendering::Canvas& canvas = gViewPointer->GetCanvas(); + + //// + //// BEGIN-EXAMPLE SaveCanvasImage + //// + canvas.SaveAs("MyVis.ppm"); + //// + //// END-EXAMPLE SaveCanvasImage + //// +} + +//// +//// BEGIN-EXAMPLE ResetCamera +//// +void ResetCamera(vtkm::rendering::View& view) +{ + vtkm::Bounds bounds = view.GetScene().GetSpatialBounds(); + view.GetCamera().ResetToBounds(bounds); + //// PAUSE-EXAMPLE + std::cout << "Position: " << view.GetCamera().GetPosition() << std::endl; + std::cout << "LookAt: " << view.GetCamera().GetLookAt() << std::endl; + std::cout << "ViewUp: " << view.GetCamera().GetViewUp() << std::endl; + std::cout << "FOV: " << view.GetCamera().GetFieldOfView() << std::endl; + std::cout << "ClipRange: " << view.GetCamera().GetClippingRange() << std::endl; + //// RESUME-EXAMPLE +} +//// +//// END-EXAMPLE ResetCamera +//// + +void ChangeCamera(vtkm::rendering::Camera& camera) +{ + // Just set some camera parameters for demonstration purposes. + //// + //// BEGIN-EXAMPLE CameraPositionOrientation + //// + camera.SetPosition(vtkm::make_Vec(10.0, 6.0, 6.0)); + camera.SetLookAt(vtkm::make_Vec(0.0, 0.0, 0.0)); + camera.SetViewUp(vtkm::make_Vec(0.0, 1.0, 0.0)); + camera.SetFieldOfView(60.0); + camera.SetClippingRange(0.1, 100.0); + //// + //// END-EXAMPLE CameraPositionOrientation + //// +} + +void ObliqueCamera(vtkm::rendering::View& view) +{ + //// + //// BEGIN-EXAMPLE AxisAlignedCamera + //// + view.GetCamera().SetPosition(vtkm::make_Vec(0.0, 0.0, 0.0)); + view.GetCamera().SetLookAt(vtkm::make_Vec(0.0, 0.0, -1.0)); + view.GetCamera().SetViewUp(vtkm::make_Vec(0.0, 1.0, 0.0)); + vtkm::Bounds bounds = view.GetScene().GetSpatialBounds(); + view.GetCamera().ResetToBounds(bounds); + //// + //// END-EXAMPLE AxisAlignedCamera + //// + //// + //// BEGIN-EXAMPLE CameraMovement + //// + view.GetCamera().Azimuth(45.0); + view.GetCamera().Elevation(45.0); + //// + //// END-EXAMPLE CameraMovement + //// +} + +void KeyPressCallback(unsigned char key, int x, int y) +{ + switch (key) + { + case 'q': + case 'Q': + delete gViewPointer; + gViewPointer = NULL; + exit(0); + break; + case 's': + case 'S': + SaveImage(); + break; + case 'r': + case 'R': + ResetCamera(*gViewPointer); + break; + case 'c': + case 'C': + ChangeCamera(gViewPointer->GetCamera()); + break; + case 'o': + case 'O': + ObliqueCamera(*gViewPointer); + } + glutPostRedisplay(); + (void)x; + (void)y; +} + +int go() +{ + // Initialize VTK-m rendering classes + vtkm::cont::DataSet surfaceData; + try + { + vtkm::io::VTKDataSetReader reader( + vtkm::cont::testing::Testing::GetTestDataBasePath() + "unstructured/cow.vtk"); + surfaceData = reader.ReadDataSet(); + } + catch (vtkm::io::ErrorIO& error) + { + std::cout << "Could not read file:" << std::endl << error.GetMessage() << std::endl; + exit(1); + } + catch (...) + { + throw; + } + + //// + //// BEGIN-EXAMPLE SpecifyColorTable + //// + vtkm::rendering::Actor actor(surfaceData.GetCellSet(), + surfaceData.GetCoordinateSystem(), + surfaceData.GetField("RandomPointScalars"), + vtkm::cont::ColorTable("inferno")); + //// + //// END-EXAMPLE SpecifyColorTable + //// + + vtkm::rendering::Scene scene; + scene.AddActor(actor); + + vtkm::rendering::MapperRayTracer mapper; + vtkm::rendering::CanvasRayTracer canvas; + + gViewPointer = new vtkm::rendering::View3D(scene, mapper, canvas); + + // Start the GLUT rendering system. This function typically does not return. + glutMainLoop(); + + return 0; +} + +int doMain(int argc, char* argv[]) +{ + // Initialize GLUT window and callbacks + glutInit(&argc, argv); + glutInitWindowSize(960, 600); + glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH); + glutCreateWindow("VTK-m Example"); + + glutDisplayFunc(DisplayCallback); + glutReshapeFunc(WindowReshapeCallback); + glutMouseFunc(MouseButtonCallback); + glutMotionFunc(MouseMoveCallback); + glutKeyboardFunc(KeyPressCallback); + + gNoInteraction = false; + for (int arg = 1; arg < argc; ++arg) + { + if (strcmp(argv[arg], "--no-interaction") == 0) + { + gNoInteraction = true; + } + } + + return vtkm::cont::testing::Testing::Run(go, argc, argv); +} + +} // anonymous namespace + +int GuideExampleRenderingInteractive(int argc, char* argv[]) +{ + return doMain(argc, argv); +} diff --git a/docs/users-guide/examples/GuideExampleRuntimeDeviceTracker.cxx b/docs/users-guide/examples/GuideExampleRuntimeDeviceTracker.cxx new file mode 100644 index 000000000..e769859f1 --- /dev/null +++ b/docs/users-guide/examples/GuideExampleRuntimeDeviceTracker.cxx @@ -0,0 +1,96 @@ +//============================================================================ +// Copyright (c) Kitware, Inc. +// All rights reserved. +// See LICENSE.txt 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 + +#include + +#include + +#include + +namespace +{ + +static const vtkm::Id ARRAY_SIZE = 10; + +void CopyWithRuntime() +{ + std::cout << "Checking runtime in copy." << std::endl; + + using T = vtkm::Float32; + vtkm::cont::ArrayHandle srcArray; + srcArray.Allocate(ARRAY_SIZE); + SetPortal(srcArray.WritePortal()); + + vtkm::cont::ArrayHandle destArray; + + //// + //// BEGIN-EXAMPLE RestrictCopyDevice + //// + vtkm::cont::ScopedRuntimeDeviceTracker tracker( + vtkm::cont::DeviceAdapterTagKokkos(), vtkm::cont::RuntimeDeviceTrackerMode::Disable); + + //// + //// BEGIN-EXAMPLE ArrayCopy + //// + vtkm::cont::ArrayCopy(srcArray, destArray); + //// + //// END-EXAMPLE ArrayCopy + //// + //// + //// END-EXAMPLE RestrictCopyDevice + //// + + VTKM_TEST_ASSERT(destArray.GetNumberOfValues() == ARRAY_SIZE, "Bad array size."); + CheckPortal(destArray.ReadPortal()); +} + +//// +//// BEGIN-EXAMPLE ForceThreadLocalDevice +//// +void ChangeDefaultRuntime() +{ + std::cout << "Checking changing default runtime." << std::endl; + + //// PAUSE-EXAMPLE +#ifdef VTKM_ENABLE_KOKKOS + //// RESUME-EXAMPLE + //// + //// BEGIN-EXAMPLE SpecifyDeviceAdapter + //// + vtkm::cont::ScopedRuntimeDeviceTracker(vtkm::cont::DeviceAdapterTagKokkos{}); + //// + //// END-EXAMPLE SpecifyDeviceAdapter + //// + //// PAUSE-EXAMPLE +#endif //VTKM_ENABLE_KOKKOS + //// RESUME-EXAMPLE + + // VTK-m operations limited to Kokkos devices here... + + // Devices restored as we leave scope. +} +//// +//// END-EXAMPLE ForceThreadLocalDevice +//// + +void Run() +{ + CopyWithRuntime(); + ChangeDefaultRuntime(); +} + +} // anonymous namespace + +int GuideExampleRuntimeDeviceTracker(int argc, char* argv[]) +{ + return vtkm::cont::testing::Testing::Run(Run, argc, argv); +} diff --git a/docs/users-guide/examples/GuideExampleTimer.cxx b/docs/users-guide/examples/GuideExampleTimer.cxx new file mode 100644 index 000000000..8956362e8 --- /dev/null +++ b/docs/users-guide/examples/GuideExampleTimer.cxx @@ -0,0 +1,61 @@ +//============================================================================ +// Copyright (c) Kitware, Inc. +// All rights reserved. +// See LICENSE.txt 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 +#include +#include + +#include + +#include +#include + +namespace +{ + +void DoTiming() +{ + vtkm::cont::DataSet dataSet = + vtkm::cont::testing::MakeTestDataSet().Make2DUniformDataSet0(); + //// + //// BEGIN-EXAMPLE Timer + //// + vtkm::filter::field_transform::PointElevation elevationFilter; + elevationFilter.SetUseCoordinateSystemAsField(true); + elevationFilter.SetOutputFieldName("elevation"); + + vtkm::cont::Timer timer; + + timer.Start(); + + vtkm::cont::DataSet result = elevationFilter.Execute(dataSet); + + // This code makes sure data is pulled back to the host in a host/device + // architecture. + vtkm::cont::ArrayHandle outArray; + result.GetField("elevation").GetData().AsArrayHandle(outArray); + outArray.SyncControlArray(); + + timer.Stop(); + + vtkm::Float64 elapsedTime = timer.GetElapsedTime(); + + std::cout << "Time to run: " << elapsedTime << std::endl; + //// + //// END-EXAMPLE Timer + //// +} + +} // anonymous namespace + +int GuideExampleTimer(int argc, char* argv[]) +{ + return vtkm::cont::testing::Testing::Run(DoTiming, argc, argv); +} diff --git a/docs/users-guide/images/AlternateRendering-EdgeRendering.png b/docs/users-guide/images/AlternateRendering-EdgeRendering.png new file mode 100644 index 000000000..b6ddd7971 --- /dev/null +++ b/docs/users-guide/images/AlternateRendering-EdgeRendering.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6b5c80dac2e4c3769231c0e0b2a547e1699403c131edcf89738b436f7471366d +size 234301 diff --git a/docs/users-guide/images/AlternateRendering-GlyphRenderingArrows.png b/docs/users-guide/images/AlternateRendering-GlyphRenderingArrows.png new file mode 100644 index 000000000..3f0ddc7aa --- /dev/null +++ b/docs/users-guide/images/AlternateRendering-GlyphRenderingArrows.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d20c5d53b1a110a432d498e2265e82112ca12f4aa3565f0fe6e27d48d833dca9 +size 135748 diff --git a/docs/users-guide/images/AlternateRendering-GlyphRenderingCubes.png b/docs/users-guide/images/AlternateRendering-GlyphRenderingCubes.png new file mode 100644 index 000000000..5b45f8092 --- /dev/null +++ b/docs/users-guide/images/AlternateRendering-GlyphRenderingCubes.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:10b421758c721d05233205327ee49c6f568e4fedd22c2a54dd1ad10584d5e4fb +size 57467 diff --git a/docs/users-guide/images/AlternateRendering-GlyphRenderingSpheres.png b/docs/users-guide/images/AlternateRendering-GlyphRenderingSpheres.png new file mode 100644 index 000000000..ead236171 --- /dev/null +++ b/docs/users-guide/images/AlternateRendering-GlyphRenderingSpheres.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:438aacdfe49160475b89062562888b43bf1fd9a5edfe5ee8e2985042ca96c69a +size 223324 diff --git a/docs/users-guide/images/AlternateRendering.png b/docs/users-guide/images/AlternateRendering.png new file mode 100644 index 000000000..b6443f49c --- /dev/null +++ b/docs/users-guide/images/AlternateRendering.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4cbad6050396e9d7b48197623f15dc67c0e3747a048ae832a51ba2942e0dd2bd +size 763001 diff --git a/docs/users-guide/images/BasicRendering.png b/docs/users-guide/images/BasicRendering.png new file mode 100644 index 000000000..965e0dd1f --- /dev/null +++ b/docs/users-guide/images/BasicRendering.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:deaf122e7e75793fa5208879c498956cdd209a5cfee5993f9a79072065816aa4 +size 198679 diff --git a/docs/users-guide/images/CameraMovement.pdf b/docs/users-guide/images/CameraMovement.pdf new file mode 100644 index 000000000..525bb3a1b --- /dev/null +++ b/docs/users-guide/images/CameraMovement.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:758d560cc3a5a0f8a88b99a75ca520fdf647d3e3cd47e456e974a89e19236604 +size 564707 diff --git a/docs/users-guide/images/CameraMovement.png b/docs/users-guide/images/CameraMovement.png new file mode 100644 index 000000000..ab145546d --- /dev/null +++ b/docs/users-guide/images/CameraMovement.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:02742a55f4c598880bbab3baa419c5a20adf5fafb3ca4cc2a6a06adbdfc00007 +size 306743 diff --git a/docs/users-guide/images/CameraPositionOrientation.pdf b/docs/users-guide/images/CameraPositionOrientation.pdf new file mode 100644 index 000000000..7ba6f513a --- /dev/null +++ b/docs/users-guide/images/CameraPositionOrientation.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c934f1896ffd881ce13032430e7dfeb06cbfaad2cbc9a69e44537e108f914657 +size 603105 diff --git a/docs/users-guide/images/CameraPositionOrientation.png b/docs/users-guide/images/CameraPositionOrientation.png new file mode 100644 index 000000000..6fd8454d6 --- /dev/null +++ b/docs/users-guide/images/CameraPositionOrientation.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e70c2d8d0341c92c0d18286a40fdd97aff810adbc0e99d2f0881bf9c7683c4a3 +size 378456 diff --git a/docs/users-guide/images/CameraViewRange2D.pdf b/docs/users-guide/images/CameraViewRange2D.pdf new file mode 100644 index 000000000..5882db512 --- /dev/null +++ b/docs/users-guide/images/CameraViewRange2D.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a6fce241ace6a4faaf0e46094b8ef3b568e680d6f50c4224ac89d4bb80d8e001 +size 288203 diff --git a/docs/users-guide/images/CameraViewRange2D.png b/docs/users-guide/images/CameraViewRange2D.png new file mode 100644 index 000000000..4b66ac6dc --- /dev/null +++ b/docs/users-guide/images/CameraViewRange2D.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cf05b1fda263a8d50c4b4d93ae43759da942545156916950889b9fa5e1c67232 +size 207691 diff --git a/docs/users-guide/images/CellConnections.png b/docs/users-guide/images/CellConnections.png new file mode 100644 index 000000000..c9103d169 --- /dev/null +++ b/docs/users-guide/images/CellConnections.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:98cbe014e742412d88ed967d4ad4b1093c37de99ffa594ff23bd999a8e24741b +size 158297 diff --git a/docs/users-guide/images/CellConnectionsHexahedron.pdf b/docs/users-guide/images/CellConnectionsHexahedron.pdf new file mode 100644 index 000000000..c217230dc --- /dev/null +++ b/docs/users-guide/images/CellConnectionsHexahedron.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:78ed51a7b522f4872a58b182c14bb53538b48bdaaf874fd3d6bdc48ab41b90a0 +size 131030 diff --git a/docs/users-guide/images/CellConnectionsHexahedron.png b/docs/users-guide/images/CellConnectionsHexahedron.png new file mode 100644 index 000000000..f2bda2565 --- /dev/null +++ b/docs/users-guide/images/CellConnectionsHexahedron.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6ab854e2fa0874127cc096790829ba4a3c5f388cacee1813bb1c348385352b76 +size 10758 diff --git a/docs/users-guide/images/CellConnectionsLine.pdf b/docs/users-guide/images/CellConnectionsLine.pdf new file mode 100644 index 000000000..e69e1e430 --- /dev/null +++ b/docs/users-guide/images/CellConnectionsLine.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:723804fe5e3fc6daa97856a6762d9d161247893ec3469f2618bc9a9f85528035 +size 83974 diff --git a/docs/users-guide/images/CellConnectionsLine.png b/docs/users-guide/images/CellConnectionsLine.png new file mode 100644 index 000000000..68b01d129 --- /dev/null +++ b/docs/users-guide/images/CellConnectionsLine.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1347eb5bde17e0d9946e32b7107b07395d014d65c27f16a5e2576506434835e7 +size 2332 diff --git a/docs/users-guide/images/CellConnectionsPolyLine.pdf b/docs/users-guide/images/CellConnectionsPolyLine.pdf new file mode 100644 index 000000000..1bcae5ee1 --- /dev/null +++ b/docs/users-guide/images/CellConnectionsPolyLine.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:664d14e73d941bf3ad67e5ceb3099f802fa464171ecbe533c97af7739643d01b +size 6570 diff --git a/docs/users-guide/images/CellConnectionsPolyLine.png b/docs/users-guide/images/CellConnectionsPolyLine.png new file mode 100644 index 000000000..dfbd60790 --- /dev/null +++ b/docs/users-guide/images/CellConnectionsPolyLine.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:924763fffb9cdf77dd2cc25af168a9fd26641d338ad41d885a90f023e80709c7 +size 4188 diff --git a/docs/users-guide/images/CellConnectionsPolygon.pdf b/docs/users-guide/images/CellConnectionsPolygon.pdf new file mode 100644 index 000000000..7116947dc --- /dev/null +++ b/docs/users-guide/images/CellConnectionsPolygon.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:51c93c35c3422f07b4a1d7b066f63e99c74f6b0a40595201ef12a324faf53b41 +size 829249 diff --git a/docs/users-guide/images/CellConnectionsPolygon.png b/docs/users-guide/images/CellConnectionsPolygon.png new file mode 100644 index 000000000..2072d9183 --- /dev/null +++ b/docs/users-guide/images/CellConnectionsPolygon.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8b212bde9e1e897fa5540d5a2075c93186f2e6a165cbb8dd125dbd1a8e49d3e0 +size 6286 diff --git a/docs/users-guide/images/CellConnectionsPyramid.pdf b/docs/users-guide/images/CellConnectionsPyramid.pdf new file mode 100644 index 000000000..cc5dceea0 --- /dev/null +++ b/docs/users-guide/images/CellConnectionsPyramid.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4b89bee998fd641b46a9f911273503721f53dcf0bbdd3992f332bcc0316f5192 +size 832940 diff --git a/docs/users-guide/images/CellConnectionsPyramid.png b/docs/users-guide/images/CellConnectionsPyramid.png new file mode 100644 index 000000000..5913e68c0 --- /dev/null +++ b/docs/users-guide/images/CellConnectionsPyramid.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ecefed13142acc7a0927e6d24d34943c1213deb98536e537b7cc9be7b0842323 +size 9077 diff --git a/docs/users-guide/images/CellConnectionsQuadrilateral.pdf b/docs/users-guide/images/CellConnectionsQuadrilateral.pdf new file mode 100644 index 000000000..0da560b7c --- /dev/null +++ b/docs/users-guide/images/CellConnectionsQuadrilateral.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6b51389f747abcf666f3eba96dafb38b7a28ab2550965ad9491b85f3563f9748 +size 126197 diff --git a/docs/users-guide/images/CellConnectionsQuadrilateral.png b/docs/users-guide/images/CellConnectionsQuadrilateral.png new file mode 100644 index 000000000..2992b0dae --- /dev/null +++ b/docs/users-guide/images/CellConnectionsQuadrilateral.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e7fa527d2a13537141deb41e7ea2d3f6b63d47d835b6272e9c14592d7a5045e5 +size 4855 diff --git a/docs/users-guide/images/CellConnectionsTetrahedron.pdf b/docs/users-guide/images/CellConnectionsTetrahedron.pdf new file mode 100644 index 000000000..fdad96453 --- /dev/null +++ b/docs/users-guide/images/CellConnectionsTetrahedron.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:efb3295e684186725074e48b9f2e9009e278cdcd2c837c3a64f0814abef5f22f +size 125623 diff --git a/docs/users-guide/images/CellConnectionsTetrahedron.png b/docs/users-guide/images/CellConnectionsTetrahedron.png new file mode 100644 index 000000000..d4b223f9b --- /dev/null +++ b/docs/users-guide/images/CellConnectionsTetrahedron.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f2a0ca582ac6b1ba633fbfb62eebace76bc156879dfd6012409b527bcd1ea179 +size 6908 diff --git a/docs/users-guide/images/CellConnectionsTriangle.pdf b/docs/users-guide/images/CellConnectionsTriangle.pdf new file mode 100644 index 000000000..6f653c1e6 --- /dev/null +++ b/docs/users-guide/images/CellConnectionsTriangle.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8b3ffed9b57b75524f2f57d864c901d461b249821c02d4f3cfd819ec6701571f +size 113562 diff --git a/docs/users-guide/images/CellConnectionsTriangle.png b/docs/users-guide/images/CellConnectionsTriangle.png new file mode 100644 index 000000000..b6c6ee17f --- /dev/null +++ b/docs/users-guide/images/CellConnectionsTriangle.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:52926a39db6c0f1a8647be9789ae8252241f9e7e52b947dfba95a6c5a0c5beac +size 4772 diff --git a/docs/users-guide/images/CellConnectionsVertex.pdf b/docs/users-guide/images/CellConnectionsVertex.pdf new file mode 100644 index 000000000..ad8e4c186 --- /dev/null +++ b/docs/users-guide/images/CellConnectionsVertex.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:de1efcb86cdbbd924b9cf4dc2da21920cdd5fe5b6382486c645b1185576fe704 +size 98229 diff --git a/docs/users-guide/images/CellConnectionsVertex.png b/docs/users-guide/images/CellConnectionsVertex.png new file mode 100644 index 000000000..5bfe27ef2 --- /dev/null +++ b/docs/users-guide/images/CellConnectionsVertex.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aac7917e99e44f20ac8b5b769501c7d76015b01ee566690237d451f3a81054c4 +size 803 diff --git a/docs/users-guide/images/CellConnectionsWedge.pdf b/docs/users-guide/images/CellConnectionsWedge.pdf new file mode 100644 index 000000000..25af3a62f --- /dev/null +++ b/docs/users-guide/images/CellConnectionsWedge.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:21fa8578a661a18bcaf0921bc49a46b2aaaa8534045c35dd3135bb438953f933 +size 127567 diff --git a/docs/users-guide/images/CellConnectionsWedge.png b/docs/users-guide/images/CellConnectionsWedge.png new file mode 100644 index 000000000..d37874bfc --- /dev/null +++ b/docs/users-guide/images/CellConnectionsWedge.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b49462de9defbe8696f567b800b439c16050f0e25060ee2ecc8fad50b3c81d80 +size 10329 diff --git a/docs/users-guide/images/CellConstituents.pdf b/docs/users-guide/images/CellConstituents.pdf new file mode 100644 index 000000000..68654ceb1 --- /dev/null +++ b/docs/users-guide/images/CellConstituents.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7b4befa54d65fa91351e9b2c6b68da2a2667148afe06b418313e04837996501f +size 99997 diff --git a/docs/users-guide/images/CellConstituents.png b/docs/users-guide/images/CellConstituents.png new file mode 100644 index 000000000..28474f5f5 --- /dev/null +++ b/docs/users-guide/images/CellConstituents.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f2e0418bfb7913e12f16b684864d436ee32e90455a2185699738715996395f25 +size 9772 diff --git a/docs/users-guide/images/ExplicitCellConnections.pdf b/docs/users-guide/images/ExplicitCellConnections.pdf new file mode 100644 index 000000000..04df5b55f --- /dev/null +++ b/docs/users-guide/images/ExplicitCellConnections.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4d97509cacd71b30c41b304205751f1b63a217d10c22c9940fb09caba623b844 +size 139916 diff --git a/docs/users-guide/images/ExplicitCellConnections.png b/docs/users-guide/images/ExplicitCellConnections.png new file mode 100644 index 000000000..fe2f12105 --- /dev/null +++ b/docs/users-guide/images/ExplicitCellConnections.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c40c66cb5b873b93e69ff71bad390f614c3a610f354ff7c29561f8e9852719a8 +size 77162 diff --git a/docs/users-guide/images/ExtrudedCellSet.pdf b/docs/users-guide/images/ExtrudedCellSet.pdf new file mode 100644 index 000000000..8df5391c7 --- /dev/null +++ b/docs/users-guide/images/ExtrudedCellSet.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:32708956f822d32f13b91d7f703588e796c720b1d465f6c4758acf9ab1adbe0b +size 71423 diff --git a/docs/users-guide/images/ExtrudedCellSet.png b/docs/users-guide/images/ExtrudedCellSet.png new file mode 100644 index 000000000..d90d97203 --- /dev/null +++ b/docs/users-guide/images/ExtrudedCellSet.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:443589bb56a3d1e0a066b2f4964e09e80b88fc97bb79188b6b007616a11c87c5 +size 93821 diff --git a/docs/users-guide/images/ImplicitBox.png b/docs/users-guide/images/ImplicitBox.png new file mode 100644 index 000000000..b408f27bd --- /dev/null +++ b/docs/users-guide/images/ImplicitBox.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b3013a10ac982aa08e062d3035c12b7a30b2a023005f37ec1a612234981b42d5 +size 42385 diff --git a/docs/users-guide/images/ImplicitCylinder.png b/docs/users-guide/images/ImplicitCylinder.png new file mode 100644 index 000000000..edb600bb4 --- /dev/null +++ b/docs/users-guide/images/ImplicitCylinder.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:18a9c8563a09528ca083e0dac9e57c742c57c2a46bdb179e54b4256278b86851 +size 102156 diff --git a/docs/users-guide/images/ImplicitFrustum.png b/docs/users-guide/images/ImplicitFrustum.png new file mode 100644 index 000000000..dc6baf8fd --- /dev/null +++ b/docs/users-guide/images/ImplicitFrustum.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f73ed769039f1509f645bde7f7f54b6db3418eb9055e814d7254bb2457a8e3ce +size 87978 diff --git a/docs/users-guide/images/ImplicitPlane.png b/docs/users-guide/images/ImplicitPlane.png new file mode 100644 index 000000000..355649de1 --- /dev/null +++ b/docs/users-guide/images/ImplicitPlane.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:deac6d7e7f164bc5f1b0de284dafc895cc5f455dc4a58aacd96689b499302744 +size 26621 diff --git a/docs/users-guide/images/ImplicitSphere.png b/docs/users-guide/images/ImplicitSphere.png new file mode 100644 index 000000000..4e219e5ce --- /dev/null +++ b/docs/users-guide/images/ImplicitSphere.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a7f4e0f22c842130c928d1a9d838d2c6bdc21d06ea6bf55067784dd73c1f7702 +size 143355 diff --git a/docs/users-guide/images/StructuredCellSet.pdf b/docs/users-guide/images/StructuredCellSet.pdf new file mode 100644 index 000000000..f3bed1c2a --- /dev/null +++ b/docs/users-guide/images/StructuredCellSet.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a1fee1ef5c9f02fefcc0507fa4185742997f45d02af111c515e327a26568ae25 +size 837224 diff --git a/docs/users-guide/images/StructuredCellSet.png b/docs/users-guide/images/StructuredCellSet.png new file mode 100644 index 000000000..46140c598 --- /dev/null +++ b/docs/users-guide/images/StructuredCellSet.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d66abf7fd51769ad196e5bb0a4eaa33c5f4904d4d1924ad45f172753136ced72 +size 58627 diff --git a/docs/users-guide/images/color-tables/Black---Blue---White.png b/docs/users-guide/images/color-tables/Black---Blue---White.png new file mode 100644 index 000000000..d34800184 --- /dev/null +++ b/docs/users-guide/images/color-tables/Black---Blue---White.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:97d3e9bfc03759ab572c4b1ad711c8a0f5f6a20021f011ef6263ba9bd960142f +size 710 diff --git a/docs/users-guide/images/color-tables/Black-Body-Radiation.png b/docs/users-guide/images/color-tables/Black-Body-Radiation.png new file mode 100644 index 000000000..e67b0ae2f --- /dev/null +++ b/docs/users-guide/images/color-tables/Black-Body-Radiation.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:de2e3b9772eaaec8c699d97380eaea681ffd70680a584b956a4fec1d65f06685 +size 710 diff --git a/docs/users-guide/images/color-tables/Blue---Green---Orange.png b/docs/users-guide/images/color-tables/Blue---Green---Orange.png new file mode 100644 index 000000000..3f8b3d9f7 --- /dev/null +++ b/docs/users-guide/images/color-tables/Blue---Green---Orange.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:13096ab8a6e32567f1a6d8deaec017a29f9218b2e46c186e185bcfc79dceb7e1 +size 710 diff --git a/docs/users-guide/images/color-tables/Blue-to-Orange.png b/docs/users-guide/images/color-tables/Blue-to-Orange.png new file mode 100644 index 000000000..f0c9140db --- /dev/null +++ b/docs/users-guide/images/color-tables/Blue-to-Orange.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3cacb8997486c98f1cd7fc9b3e0bb6e06c5dba55b3ea48b37b9297a666acae77 +size 710 diff --git a/docs/users-guide/images/color-tables/Cold-and-Hot.png b/docs/users-guide/images/color-tables/Cold-and-Hot.png new file mode 100644 index 000000000..36642a3dd --- /dev/null +++ b/docs/users-guide/images/color-tables/Cold-and-Hot.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f0e3e25b3c2a93c84d026ae06c5e393c7fef58327d05ffc22746db2c4e59c658 +size 710 diff --git a/docs/users-guide/images/color-tables/Cool-to-Warm-Extended.png b/docs/users-guide/images/color-tables/Cool-to-Warm-Extended.png new file mode 100644 index 000000000..ede175c07 --- /dev/null +++ b/docs/users-guide/images/color-tables/Cool-to-Warm-Extended.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:76021841fdc1c4c1d32b79cffd834b0eead0b85716ac486d7602d922407a91f0 +size 710 diff --git a/docs/users-guide/images/color-tables/Cool-to-Warm.png b/docs/users-guide/images/color-tables/Cool-to-Warm.png new file mode 100644 index 000000000..59aff8013 --- /dev/null +++ b/docs/users-guide/images/color-tables/Cool-to-Warm.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:11cfb6b9267fee3bb2f3e1b07bcb43b1105d8c68b6ae8605719f8e48e582dc27 +size 710 diff --git a/docs/users-guide/images/color-tables/Default.png b/docs/users-guide/images/color-tables/Default.png new file mode 100644 index 000000000..9f5032dc3 --- /dev/null +++ b/docs/users-guide/images/color-tables/Default.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e3c8b2ba6bd8639fc4f5b8ba50c743567a4acaaa66a4be8421f36a8a0545daa5 +size 710 diff --git a/docs/users-guide/images/color-tables/Gray-to-Red.png b/docs/users-guide/images/color-tables/Gray-to-Red.png new file mode 100644 index 000000000..fe200edf5 --- /dev/null +++ b/docs/users-guide/images/color-tables/Gray-to-Red.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ecfe7e948e186cf0b436c3bf38cd7ee19ab61fc4c5619517d0c5e883e93e74c5 +size 710 diff --git a/docs/users-guide/images/color-tables/Green.png b/docs/users-guide/images/color-tables/Green.png new file mode 100644 index 000000000..d2250a2f3 --- /dev/null +++ b/docs/users-guide/images/color-tables/Green.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:162964095a43d62297824ba398acc5588af374c4c23c8fe702630954157cc202 +size 710 diff --git a/docs/users-guide/images/color-tables/Inferno.png b/docs/users-guide/images/color-tables/Inferno.png new file mode 100644 index 000000000..aa6ddb151 --- /dev/null +++ b/docs/users-guide/images/color-tables/Inferno.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3eec2a47ca94682bd4fcb00b9119c93f5fe27393fd89c3cc6dbc609f8467c3a8 +size 710 diff --git a/docs/users-guide/images/color-tables/Jet.png b/docs/users-guide/images/color-tables/Jet.png new file mode 100644 index 000000000..9cd3fc06b --- /dev/null +++ b/docs/users-guide/images/color-tables/Jet.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c4968a413aa94ae33904eb4850115bae0cb451c87fa6c32e235ff1bdf4a8253d +size 710 diff --git a/docs/users-guide/images/color-tables/Plasma.png b/docs/users-guide/images/color-tables/Plasma.png new file mode 100644 index 000000000..b88034270 --- /dev/null +++ b/docs/users-guide/images/color-tables/Plasma.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a2ff1a172ab843948e6df0d8c01e4ca64b2255e3a16c1c78da23d3d99f6dada2 +size 710 diff --git a/docs/users-guide/images/color-tables/Rainbow-Desaturated.png b/docs/users-guide/images/color-tables/Rainbow-Desaturated.png new file mode 100644 index 000000000..3d02aa4d9 --- /dev/null +++ b/docs/users-guide/images/color-tables/Rainbow-Desaturated.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ca734ced93f979f6da689712865c1529f6be4eff61ade50ee633b76d9321a783 +size 710 diff --git a/docs/users-guide/images/color-tables/Rainbow-Uniform.png b/docs/users-guide/images/color-tables/Rainbow-Uniform.png new file mode 100644 index 000000000..1d5f5d134 --- /dev/null +++ b/docs/users-guide/images/color-tables/Rainbow-Uniform.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ebc251a5676c6d9e85d49521b3cd1062223c58b6e6823b84ad85d9d0500c6225 +size 710 diff --git a/docs/users-guide/images/color-tables/Viridis.png b/docs/users-guide/images/color-tables/Viridis.png new file mode 100644 index 000000000..9f5032dc3 --- /dev/null +++ b/docs/users-guide/images/color-tables/Viridis.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e3c8b2ba6bd8639fc4f5b8ba50c743567a4acaaa66a4be8421f36a8a0545daa5 +size 710 diff --git a/docs/users-guide/images/color-tables/X-Ray.png b/docs/users-guide/images/color-tables/X-Ray.png new file mode 100644 index 000000000..c1fb04cc7 --- /dev/null +++ b/docs/users-guide/images/color-tables/X-Ray.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0d1874a353f071bad1f3a53789daabd001e6e26393f9194db7c2377a116a01b5 +size 114 diff --git a/docs/users-guide/images/color-tables/Yellow---Gray---Blue.png b/docs/users-guide/images/color-tables/Yellow---Gray---Blue.png new file mode 100644 index 000000000..ea04cb915 --- /dev/null +++ b/docs/users-guide/images/color-tables/Yellow---Gray---Blue.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:56044dca0b9521811a8c2947eaf13d63960e1b597ce33c2cea024efe753cc83a +size 710 diff --git a/docs/users-guide/implicit-functions.rst b/docs/users-guide/implicit-functions.rst new file mode 100644 index 000000000..f8affaf74 --- /dev/null +++ b/docs/users-guide/implicit-functions.rst @@ -0,0 +1,167 @@ +============================== +Implicit Functions +============================== + +.. index:: implicit function +.. index:: functions; implicit + +|VTKm|'s implicit functions are objects that are constructed with values representing 3D spatial coordinates that often describe a shape. +Each implicit function is typically defined by the surface formed where the value of the function is equal to 0. +All implicit functions implement ``Value()`` and ``Gradient()`` methods that describe the orientation of a provided point with respect to the implicit function's shape. + +The ``Value()`` method for an implicit function takes a :type:`vtkm::Vec3f` and returns a :type:`vtkm::FloatDefault` representing the orientation of the point with respect to the implicit function's shape. +Negative scalar values represent vector points inside of the implicit function's shape. +Positive scalar values represent vector points outside the implicit function's shape. +Zero values represent vector points that lie on the surface of the implicit function. + +The ``Gradient()`` method for an implicit function takes a :type:`vtkm::Vec3f` and returns a :type:`vtkm::Vec3f` representing the pointing direction from the implicit function's shape. +Gradient calculations are more object shape specific. +It is advised to look at the individual shape implementations for specific implicit functions. + +Implicit functions are useful when trying to clip regions from a dataset. +For example, it is possible to use :class:`vtkm::filter::contour::ClipWithImplicitFunction` to remove a region in a provided dataset according to the shape of an implicit function. +See :secref:`provided-filters:Clip with Implicit Function` for more information on clipping with implicit functions. + +|VTKm| has implementations of various implicit functions provided by the following subclasses. + +------------------------------ +Plane +------------------------------ + +.. index:: + double: implicit function; plane + +:class:`vtkm::Plane` defines an infinite plane. +The plane is defined by a pair of :type:`vtkm::Vec3f` values that represent the origin, which is any point on the plane, and a normal, which is a vector that is tangent to the plane. +These are set with the :func:`vtkm::Plane::SetOrigin` and :func:`vtkm::Plane::SetNormal` methods, respectively. +Planes extend infinitely from the origin point in the direction perpendicular form the Normal. +An example :class:`vtkm::Plane` is shown in :numref:`fig:ImplicitPlane`. + +.. figure:: images/ImplicitPlane.png + :width: 2.5in + :name: fig:ImplicitPlane + + Visual Representation of an Implicit Plane. + The red dot and arrow represent the origin and normal of the plane, respectively. + For demonstrative purposes the plane as shown with limited area, but in actuality the plane extends infinitely. + +.. doxygenclass:: vtkm::Plane + :members: + +------------------------------ +Sphere +------------------------------ + +.. index:: + double: implicit function; sphere + +:class:`vtkm::Sphere` defines a sphere. +The :class:`vtkm::Sphere` is defined by a center location and a radius, which are set with the :func:`vtkm::Sphere::SetCenter` and :func:`vtkm::Sphere::SetRadius` methods, respectively. +An example :class:`vtkm::Sphere` is shown in :numref:`fig:ImplicitSphere`. + +.. figure:: images/ImplicitSphere.png + :width: width=2.5in + :name: fig:ImplicitSphere + + Visual Representation of an Implicit Sphere. + The red dot represents the center of the sphere. + The radius is the length of any line (like the blue one shown here) that extends from the center in any direction to the surface. + +.. doxygenclass:: vtkm::Sphere + :members: + + +------------------------------ +Cylinder +------------------------------ + +.. index:: + double: implicit function; cylinder + +:class:`vtkm::Cylinder` defines a cylinder that extends infinitely along its axis. +The cylinder is defined with a center point, a direction of the center axis, and a radius, which are set with :func:`vtkm::Cylinder::SetCenter`, :func:`vtkm::Cylinder::SetAxis`, and :func:`vtkm::Cylinder::SetRadius`, respectively. +An example :class:`vtkm::Cylinder` is shown in :numref:`fig:ImplicitCylinder` with set origin, radius, and axis values. + +.. figure:: images/ImplicitCylinder.png + :width: 2.5in + :name: fig:ImplicitCylinder + + Visual Representation of an Implicit Cylinder. + The red dot represents the center value, and the red arrow represents the vector that points in the direction of the axis. + The radius is the length of any line (like the blue one shown here) that extends perpendicular from the axis to the surface. + +.. doxygenclass:: vtkm::Cylinder + :members: + + +------------------------------ +Box +------------------------------ + +.. index:: + double:: implicit function; box + +:class:`vtkm::Box` defines an axis-aligned box. +The box is defined with a pair of :type:`vtkm::Vec3f` values that represent the minimum point coordinates and maximum point coordinates, which are set with :func:`vtkm::Box::SetMinPoint` and :func:`vtkm::Box::SetMaxPoint`, respectively. +The :class:`vtkm::Box` is the shape enclosed by intersecting axis-parallel lines drawn from each point. +Alternately, the :class:`vtkm::Box` can be specified with a :class:`vtkm::Bounds` object using the :func:`vtkm::Box::SetBounds` method. +An example :class:`vtkm::Box` is shown in :numref:`fig:ImplicitBox`. + +.. figure:: images/ImplicitBox.png + :width: 2.5in + :name: fig:ImplicitBox + + Visual Representation of an Implicit Box. + The red dots represent the minimum and maximum points. + +.. doxygenclass:: vtkm::Box + :members: + + +------------------------------ +Frustum +------------------------------ + +.. index:: + double: implicit function; frustum + +:class:`vtkm::Frustum` defines a hexahedral region with potentially oblique faces. +A :class:`vtkm::Frustum` is typically used to define the tapered region of space visible in a perspective camera projection. +The frustum is defined by the 6 planes that make up its 6 faces. +Each plane is defined by a point and a normal vector, which are set with :func:`vtkm::Frustum::SetPlane` and :func:`vtkm::Frustum::SetNormal`, respectively. +Parameters for all 6 planes can be set at once using the :func:`vtkm::Frustum::SetPlanes` and :func:`vtkm::Frustum::SetNormals` methods. +Alternately, the :class:`vtkm::Frustum` can be defined by the 8 points at the vertices of the enclosing hexahedron using the :func:`vtkm::Frustum::CreateFromPoints` method. +The points given to :func:`vtkm::Frustum::CreateFromPoints` must be in hex-cell order where the first four points are assumed to be a plane, and the last four points are assumed to be a plane. +An example :class:`vtkm::Frustum` is shown in :numref:`fig:ImplicitFrustum`. + +.. figure:: images/ImplicitFrustum.png + :width: 2.5in + :name: fig:ImplicitFrustum + + Visual Representation of an Implicit Frustum. + The red dots and arrows represent the points and normals defining each enclosing plane. + The blue dots represent the 8 vertices, which can also be used to define the frustum. + +.. doxygenclass:: vtkm::Frustum + + +------------------------------ +General Implicit Functions +------------------------------ + +.. index:: + double: implicit function; general + +It is often the case when creating code that uses an implicit function that you do not know which implicit function will be desired. +For example, the :class:`vtkm::filter::contour::ClipWithImplicitFunction` filter can be used with any of the implicit functions described here (:class:`vtkm::Plane`, :class:`vtkm::Sphere`, etc.). + +To handle conditions where you want to support multiple implicit functions simultaneously, |VTKm| provides :class:`vtkm::ImplicitFunctionGeneral`. +Any of the implicit functions described in this chapter can be copied to a :class:`vtkm::ImplicitFunctionGeneral`, which will behave like the specified function. +The following example shows shows passing a :class:`vtkm::Sphere` to :class:`vtkm::filter::contour::ClipWithImplicitFunction`, which internally uses :class:`vtkm::ImplicitFunctionGeneral` to manage the implicit function types. + +.. load-example:: ImplicitFunctionGeneral + :file: GuideExampleProvidedFilters.cxx + :caption: Passing an implicit function to a filter. + +.. doxygenclass:: vtkm::ImplicitFunctionGeneral + :members: diff --git a/docs/users-guide/initialization.rst b/docs/users-guide/initialization.rst new file mode 100644 index 000000000..16fd8fc60 --- /dev/null +++ b/docs/users-guide/initialization.rst @@ -0,0 +1,35 @@ +============================== +Initialization +============================== + +.. index:: initialization + +When it comes to running |VTKm| code, there are a few ways in which various facilities, such as logging device connections, and device configuration parameters, can be initialized. +The preferred method of initializing these features is to run the :func:`vtkm::cont::Initialize` function. +Although it is not strictly necessary to call :func:`vtkm::cont::Initialize`, it is recommended to set up state and check for available devices. + +.. doxygenfunction:: vtkm::cont::Initialize(int &argc, char *argv[], InitializeOptions opts) + +.. index:: + single: argc + single: argv + +:func:`vtkm::cont::Initialize` can be called without any arguments, in which case |VTKm| will be initialized with defaults. +But it can also optionally take the ``argc`` and ``argv`` arguments to the ``main`` function to parse some options that control the state of |VTKm|. +|VTKm| accepts arguments that, for example, configure the compute device to use or establish logging levels. +Any arguments that are handled by |VTKm| are removed from the ``argc``/``argv`` list so that your program can then respond to the remaining arguments. + +:func:`vtkm::cont::Initialize` returns a :struct:`vtkm::cont::InitializeResult` structure. +This structure contains information about the supported arguments and options selected during initialization. + +.. doxygenstruct:: vtkm::cont::InitializeResult + :members: + +:func:`vtkm::cont::Initialize` takes an optional third argument that specifies some options on the behavior of the argument parsing. +The options are specified as a bit-wise "or" of fields specified in the :enum:`vtkm::cont::InitializeOptions` enum. + +.. doxygenenum:: vtkm::cont::InitializeOptions + +.. load-example:: BasicInitialize + :file: GuideExampleInitialization.cxx + :caption: Calling :func:`vtkm::cont::Initialize`. diff --git a/docs/users-guide/io.rst b/docs/users-guide/io.rst new file mode 100644 index 000000000..0af979f7b --- /dev/null +++ b/docs/users-guide/io.rst @@ -0,0 +1,143 @@ +============================== +File I/O +============================== + +.. index:: + single: I/O + single: file I/O + +Before |VTKm| can be used to process data, data need to be loaded into the +system. +|VTKm| comes with a basic file I/O package to get started developing very +quickly. +All the file I/O classes are declared under the ``vtkm::io`` namespace. + +.. didyouknow:: + Files are just one of many ways to get data in and out of |VTKm|. + In later chapters we explore ways to define |VTKm| data structures of + increasing power and complexity. + In particular, :secref:`dataset:Building Data Sets` describes how to build |VTKm| data set objects and Section \ref{sec:ArrayHandle:Adapting} documents how to adapt data structures defined in other libraries to be used directly in |VTKm|. + +.. todo:: Add ArrayHandle section reference above. + +------------------------------ +Readers +------------------------------ + +.. index:: + single: file I/O; read + single: read file + +All reader classes provided by |VTKm| are located in the ``vtkm::io`` +namespace. +The general interface for each reader class is to accept a filename in the constructor and to provide a ``ReadDataSet`` method to load the data from disk. + +The data in the file are returned in a :class:`vtkm::cont::DataSet` object +as described in :chapref:`dataset:Data Sets`, but it is sufficient to know that a ``DataSet`` can be passed among readers, writers, filters, and rendering units. + +Legacy VTK File Reader +============================== + +Legacy VTK files are a simple open format for storing visualization data. +These files typically have a :file:`.vtk` extension. +Legacy VTK files are popular because they are simple to create and read and +are consequently supported by a large number of tools. +The format of legacy VTK files is well documented in *The VTK User's +Guide* [as well as online](https://examples.vtk.org/site/VTKFileFormats/). +Legacy VTK files can also be read and written with tools like ParaView and VisIt. + +Legacy VTK files can be read using the :class:`vtkm::io::VTKDataSetReader` class. + +.. doxygenclass:: vtkm::io::VTKDataSetReader + :members: + +.. load-example:: VTKDataSetReader + :file: GuideExampleIO.cxx + :caption: Reading a legacy VTK file. + +Image Readers +============================== + +|VTKm| provides classes to read images from some standard image formats. +These readers will store the data in a :class:`vtkm::cont::DataSet` object with the colors stored as a named point field. +The colors are read as 4-component RGBA vectors for each pixel. +Each component in the pixel color is stored as a 32-bit float between 0 and 1. + +Portable Network Graphics (PNG) files can be read using the :class:`vtkm::io::ImageReaderPNG` class. + +.. doxygenclass:: vtkm::io::ImageReaderPNG + :members: + +.. load-example:: ImageReaderPNG + :file: GuideExampleIO.cxx + :caption: Reading an image from a PNG file. + +Portable anymap (PNM) files can be read using the :class:`vtkm::io::ImageReaderPNM` class. + +.. doxygenclass:: vtkm::io::ImageReaderPNM + :members: + +Like for PNG files, a :class:`vtkm::io::ImageReaderPNM` is constructed with the name of the file to read from. + +.. load-example:: ImageReaderPNM + :file: GuideExampleIO.cxx + :caption: Reading an image from a PNM file. + + +------------------------------ +Writers +------------------------------ + +.. index:: + single: file I/O; write + single: write file + +All writer classes provided by |VTKm| are located in the ``vtkm::io`` namespace. +The general interface for each writer class is to accept a filename in the constructor and to provide a ``WriteDataSet`` method to save data to the disk. +The ``WriteDataSet`` method takes a :class:`vtkm::cont::DataSet` object as an argument, which contains the data to write to the file. + +Legacy VTK File Writer +============================== + +Legacy VTK files can be written using the :class:`vtkm::io::VTKDataSetWriter` class. + +.. doxygenclass:: vtkm::io::VTKDataSetWriter + :members: + +.. doxygenenum:: vtkm::io::FileType + +.. load-example:: VTKDataSetWriter + :file: GuideExampleIO.cxx + :caption: Writing a legacy VTK file. + +Image Writers +============================== + +|VTKm| provides classes to some standard image formats. +These writers store data in a :class:`vtkm::cont::DataSet`. +The data must be a 2D structure with the colors stored in a point field. +(See :chapref:`dataset:Data Sets` for details on :class:`vtkm::cont::DataSet` objects.) + +Portable Network Graphics (PNG) files can be written using the :class:`vtkm::io::ImageWriterPNG` class. + +.. doxygenclass:: vtkm::io::ImageWriterPNG + :members: + +By default, PNG files are written as RGBA colors using 8-bits for each component. +You can change the format written using the :func:`vtkm::io::ImageWriterPNG::SetPixelDepth` method. +This takes an item in the :enum:`vtkm::io::ImageWriterPNG::PixelDepth` enumeration. + +.. doxygenenum:: vtkm::io::ImageWriterBase::PixelDepth + +.. load-example:: ImageWriterPNG + :file: GuideExampleIO.cxx + :caption: Writing an image to a PNG file. + +Portable anymap (PNM) files can be written using the :class:`vtkm::io::ImageWriterPNM` class. + +.. doxygenclass:: vtkm::io::ImageWriterPNM + :members: + +.. load-example:: ImageWriterPNM + :file: GuideExampleIO.cxx + :caption: Writing an image to a PNM file. diff --git a/docs/users-guide/managing-devices.rst b/docs/users-guide/managing-devices.rst new file mode 100644 index 000000000..c9daf62b0 --- /dev/null +++ b/docs/users-guide/managing-devices.rst @@ -0,0 +1,167 @@ +============================== +Managing Devices +============================== + +Multiple vendors vie to provide accelerator-type processors. +|VTKm| endeavors to support as many such architectures as possible. +Each device and device technology requires some level of code specialization, and that specialization is encapsulated in a unit called a :index:`device adapter`. + +So far in :partref:`part-using:Using |VTKm|` we have been writing code that runs on a local serial CPU. +In those examples where we run a filter, |VTKm| is launching parallel execution in the execution environment. +Internally |VTKm| uses a device adapter to manage this execution. + +A build of |VTKm| generally supports multiple device adapters. +In this chapter we describe how to represent and manage devices. + + +------------------------------ +Device Adapter Tag +------------------------------ + +.. index:: + double: device adapter; tag + +A device adapter is identified by a *device adapter tag*. +This tag, which is simply an empty struct type, is used as the template parameter for several classes in the |VTKm| control environment and causes these classes to direct their work to a particular device. +The following device adapter tags are available in |VTKm|. + +.. index:: serial +.. doxygenstruct:: vtkm::cont::DeviceAdapterTagSerial +.. index:: cuda +.. doxygenstruct:: vtkm::cont::DeviceAdapterTagCuda +.. index:: OpenMP +.. doxygenstruct:: vtkm::cont::DeviceAdapterTagOpenMP +.. index:: Intel Threading Building Blocks +.. index:: TBB +.. doxygenstruct:: vtkm::cont::DeviceAdapterTagTBB +.. index:: Kokkos +.. doxygenstruct:: vtkm::cont::DeviceAdapterTagKokkos + +The following example uses the tag for the Kokkos device adapter to specify a specific device for |VTKm| to use. +(Details on specifying devices in |VTKm| is provided in :secref:`managing-devices:Specifying Devices`.) + +.. load-example:: SpecifyDeviceAdapter + :file: GuideExampleRuntimeDeviceTracker.cxx + :caption: Specifying a device using a device adapter tag. + +For classes and methods that have a template argument that is expected to be a device adapter tag, the tag type can be checked with the :c:macro:`VTKM_IS_DEVICE_ADAPTER_TAG` macro to verify the type is a valid device adapter tag. +It is good practice to check unknown types with this macro to prevent further unexpected errors. + +.. + Functions, methods, and classes that directly use device adapter tags are usually templated on the device adapter tag. + This allows the function or class to be applied to any type of device specified at compile time. + + .. load-example:: DeviceTemplateArg + :file: GuideExampleRuntimeDeviceTracker.cxx + :caption: Specifying a device using template parameters. + + .. commonerrors:: + A device adapter tag is a class just like every other type in C++. + Thus it is possible to accidently use a type that is not a device adapter tag when one is expected as a template argument. + This leads to unexpected errors in strange parts of the code. + To help identify these errors, it is good practice to use the :c:macro:`VTKM_IS_DEVICE_ADAPTER_TAG` macro to verify the type is a valid device adapter tag. + :numref:`ex:DeviceTemplateArg` uses this macro on line 4. + + +------------------------------ +Device Adapter Id +------------------------------ + +.. index:: + double: device adapter; id + +Using a device adapter tag directly means that the type of device needs to be known at compile time. +To store a device adapter type at run time, one can instead use :struct:`vtkm::cont::DeviceAdapterId`. +:struct:`vtkm::cont::DeviceAdapterId` is a superclass to all the device adapter tags, and any device adapter tag can be "stored" in a :struct:`vtkm::cont::DeviceAdapterId`. +Thus, it is more common for functions and classes to use :struct:`vtkm::cont::DeviceAdapterId` then to try to track a specific device with templated code. + +.. doxygenstruct:: vtkm::cont::DeviceAdapterId + :members: + +.. didyouknow:: + As a cheat, all device adapter tags actually inherit from the :struct:`vtkm::cont::DeviceAdapterId` class. + Thus, all of these methods can be called directly on a device adapter tag. + +.. commonerrors:: + Just because the :func:`vtkm::cont::DeviceAdapterId::IsValueValid` returns true that does not necessarily mean that this device is available to be run on. + It simply means that the device is implemented in |VTKm|. + However, that device might not be compiled, or that device might not be available on the current running system, or that device might not be enabled. + Use the device runtime tracker described in :secref:`managing-devices:Runtime Device Tracker` to determine if a particular device can actually be used. + +In addition to the provided device adapter tags listed previously, a :struct:`vtkm::cont::DeviceAdapterId` can store some special device adapter tags that do not directly specify a specific device. + +.. index:: device adapter; any +.. doxygenstruct:: vtkm::cont::DeviceAdapterTagAny + +.. index:: device adapter; undefined +.. doxygenstruct:: vtkm::cont::DeviceAdapterTagUndefined + +.. didyouknow:: + Any device adapter tag can be used where a device adapter id is expected. + Thus, you can use a device adapter tag whenever you want to specify a particular device and pass that to any method expecting a device id. + Likewise, it is usually more convenient for classes and methods to manage device adapter ids rather than device adapter tag. + + +------------------------------ +Runtime Device Tracker +------------------------------ + +.. index:: + single: runtime device tracker + single: device adapter; runtime tracker + +It is often the case that you are agnostic about what device |VTKm| algorithms run so long as they complete correctly and as fast as possible. +Thus, rather than directly specify a device adapter, you would like |VTKm| to try using the best available device, and if that does not work try a different device. +Because of this, there are many features in |VTKm| that behave this way. +For example, you may have noticed that running filters, as in the examples of :chapref:`running-filters:Running Filters`, you do not need to specify a device; they choose a device for you. + +However, even though we often would like |VTKm| to choose a device for us, we still need a way to manage device preferences. +|VTKm| also needs a mechanism to record runtime information about what devices are available so that it does not have to continually try (and fail) to use devices that are not available at runtime. +These needs are met with the :class:`vtkm::cont::RuntimeDeviceTracker` class. +:class:`vtkm::cont::RuntimeDeviceTracker` maintains information about which devices can and should be run on. +|VTKm| maintains a :class:`vtkm::cont::RuntimeDeviceTracker` for each thread your code is operating on. +To get the runtime device for the current thread, use the :func:`vtkm::cont::GetRuntimeDeviceTracker` method. + +.. doxygenfunction:: vtkm::cont::GetRuntimeDeviceTracker + +.. doxygenclass:: vtkm::cont::RuntimeDeviceTracker + :members: + +.. index:: + single: runtime device tracker; scoped + single: device adapter; scoped runtime tracker + single: scoped device adapter + + +------------------------------ +Specifying Devices +------------------------------ + +A :class:`vtkm::cont::RuntimeDeviceTracker` can be used to specify which devices to consider for a particular operation. +However, a better way to specify devices is to use the :class:`vtkm::cont::ScopedRuntimeDeviceTracker` class. +When a :class:`vtkm::cont::ScopedRuntimeDeviceTracker` is constructed, it specifies a new set of devices for |VTKm| to use. +When the :class:`vtkm::cont::ScopedRuntimeDeviceTracker` is destroyed as it leaves scope, it restores |VTKm|'s devices to those that existed when it was created. + +.. doxygenclass:: vtkm::cont::ScopedRuntimeDeviceTracker + :members: + +The following example demonstrates how the :class:`vtkm::cont::ScopedRuntimeDeviceTracker` is used to force the |VTKm| operations that happen within a function to operate exclusively with the Kokkos device. + +.. load-example:: ForceThreadLocalDevice + :file: GuideExampleRuntimeDeviceTracker.cxx + :caption: Restricting which devices |VTKm| uses per thread. + +In the previous example we forced |VTKm| to use the Kokkos device. +This is the default behavior of :class:`vtkm::cont::ScopedRuntimeDeviceTracker`, but the constructor takes an optional second argument that is a value in the :enum:`vtkm::cont::RuntimeDeviceTrackerMode` to specify how modify the current device adapter list. + +.. doxygenenum:: RuntimeDeviceTrackerMode + +As a motivating example, let us say that we want to perform a deep copy of an array (described in Section~\ref{sec:DeepArrayCopies}). +However, we do not want to do the copy on a Kokkos device because we happen to know the data is not on that device and we do not want to spend the time to transfer the data to that device. +We can use a :class:`vtkm::cont::ScopedRuntimeDeviceTracker` to temporarily disable the Kokkos device for this operation. + +.. todo:: Fix reference above. + +.. load-example:: RestrictCopyDevice + :file: GuideExampleRuntimeDeviceTracker.cxx + :caption: Disabling a device with :class:`vtkm::cont::RuntimeDeviceTracker`. diff --git a/docs/users-guide/part-using.rst b/docs/users-guide/part-using.rst index 91f3bfe65..31826a492 100644 --- a/docs/users-guide/part-using.rst +++ b/docs/users-guide/part-using.rst @@ -6,3 +6,14 @@ Using |VTKm| :maxdepth: 2 base-types.rst + version.rst + initialization.rst + dataset.rst + io.rst + running-filters.rst + provided-filters.rst + rendering.rst + error-handling.rst + managing-devices.rst + timer.rst + implicit-functions.rst diff --git a/docs/users-guide/provided-filters.rst b/docs/users-guide/provided-filters.rst new file mode 100644 index 000000000..39b8ef774 --- /dev/null +++ b/docs/users-guide/provided-filters.rst @@ -0,0 +1,1150 @@ +------------------------------ +Provided Filters +------------------------------ + +|VTKm| comes with the implementation of many filters. +Filters in |VTKm| are divided into a collection of modules, each with its own namespace and library. +This section is organized by each filter module, each of which contains one or more filters that are related to each other. + +Note that this is not an exhaustive list of filters available in |VTKm|. +More can be found in the namespaces under ``vtkm::filter`` (and likewise the subdirectories under :file:`vtkm/filter` in the |VTKm| source. + +.. + Common filter methods: + SetActiveField, GetActiveField, SetUseCoordinateSystemAsField, GetUseCoordinateSystemAsField, SetActiveCoordinateSystem, GetActiveCoordinateSystem, SetOutputFieldName, GetOutputFieldName, Execute + +.. + % These commands are used in the bottom of a description environment used for methods on filters. All should provide whichever ones make the most sense. All these commands take an optional argument that has a list of methods to supress (i.e. _not_ document) for those that are not relevant to the filter or should be documented in a different way. + + % This has the base methods available on all filters. + \NewDocumentCommand{\commonfiltermethods}{O{}}{ + \IfSubStr{#1}{Execute}{}{ + \item[\textcode{Execute}] + Takes a data set, executes the filter on a device, and returns a data set that contains the result. + } + \IfSubStr{#1}{FieldsToPass}{}{ + \item[\textcode{SetFieldsToPass}/\textcode{GetFieldsToPass}] + Specifies which fields to pass from input to output. + By default all fields are passed. + See Section~\ref{sec:FilterPassingFields} for more details. + } + } + + \NewDocumentCommand{\commonfieldfiltermethods}{O{}}{ + \IfSubStr{#1}{ActiveField}{}{ + \item[\textcode{SetActiveField}/\textcode{GetActiveFieldName}] + Specifies the name of the field to use as input. + } + \IfSubStr{#1}{UseCoordinateSystemAsField}{}{ + \item[\textcode{SetUseCoordinateSystemAsField}/\textcode{GetUseCoordinateSystemAsField}] + Specifies a Boolean flag that determines whether to use point coordinates as the input field. + Set to false by default. + When true, the values for the active field are ignored and the active coordinate system is used instead. + } + \IfSubStr{#1}{ActiveCoordinateSystem}{}{ + \item[\textcode{SetActiveCoordinateSystem}/\textcode{GetActiveCoordinateSystemIndex}] + Specifies the index of which coordinate system to use as the input field. + The default index is 0, which is the first coordinate system. + } + \IfSubStr{#1}{OutputFieldName}{}{ + \item[\textcode{SetOutputFieldName}/\textcode{GetOutputFieldName}] + Specifies the name of the output field generated. + } + \commonfiltermethods[#1] + } + + % Obsolete in new filter structure (use \commonfiltermethods) + \NewDocumentCommand{\commondatasetfiltermethods}{O{}}{ + \IfSubStr{#1}{ActiveCoordinateSystem}{}{ + \item[\textcode{SetActiveCoordinateSystem}/\textcode{GetActiveCoordinateSystemIndex}] + Specifies the index of which coordinate system to use as when computing spatial locations in the mesh. + The default index is 0, which is the first coordinate system. + } + \commonfiltermethods[#1] + } + + % Obsolete in new filter structure (use \commonfieldfiltermethods) + \NewDocumentCommand{\commondatasetwithfieldfiltermethods}{O{}}{ + \IfSubStr{#1}{ActiveField}{}{ + \item[\textcode{SetActiveField}/\textcode{GetActiveFieldName}] + Specifies the name of the field to use as input. + } + \IfSubStr{#1}{UseCoordinateSystemAsField}{}{ + \item[\textcode{SetUseCoordinateSystemAsField}/\textcode{GetUseCoordinateSystemAsField}] + Specifies a Boolean flag that determines whether to use point coordinates as the input field. + Set to false by default. + When true, the values for the active field are ignored. + } + \IfSubStr{#1}{ActiveCoordinateSystem}{}{ + \item[\textcode{SetActiveCoordinateSystem}/\textcode{GetActiveCoordinateSystemIndex}] + Specifies the index of which coordinate system to use as when computing spatial locations in the mesh. + The default index is 0, which is the first coordinate system. + } + \commonfiltermethods[#1] + } + + +Cleaning Grids +============================== + +.. index:: + double: clean grid; filter + single: data set; clean + +The ``vtkm::filter::clean_grid`` module contains filters that resolve issues with mesh structure. +This could include finding and merging coincident points, removing degenerate cells, or converting the grid to a known type. + +Clean Grid +------------------------------ + +:class:`vtkm::filter::clean_grid::CleanGrid` is a filter that converts a cell set to an explicit representation and potentially removes redundant or unused data. +It does this by iterating over all cells in the data set, and for each one creating the explicit cell representation that is stored in the output. +(Explicit cell sets are described in :secref:`dataset:Explicit Cell Sets`.) +One benefit of using :class:`vtkm::filter::clean_grid::CleanGrid` is that it can optionally remove unused points and combine coincident points. +Another benefit is that the resulting cell set will be of a known specific type. + +.. commonerrors:: + The result of :class:`vtkm::filter::clean_grid::CleanGrid` is not necessarily smaller, memory-wise, than its input. + For example, "cleaning" a data set with a structured topology will actually result in a data set that requires much more memory to store an explicit topology. + +.. doxygenclass:: vtkm::filter::clean_grid::CleanGrid + :members: + +Connected Components +============================== + +.. index:: + double: connected components; filter + +Connected components in a mesh are groups of mesh elements that are connected together in some way. +For example, if two cells are neighbors, then they are in the same component. +Likewise, a cell is also in the same component as its neighbor's neighbors as well as their neighbors and so on. +Connected components help identify when features in a simulation fragment or meld. + +The ``vtkm::filter::connected_components`` module contains filters that find groups of cells that are connected. +There are different ways to define what it means to be connected. +One way is to use the topological connections of the cells. +That is, two cells that share a point, edge, or face are connected. +Another way is to use a field that classifies each cell, and cells are only connected if they have the same classification. + +Cell Connectivity +------------------------------ + +.. index:: connected components; cell + +The :class:`vtkm::filter::connected_components::CellSetConnectivity` filter finds groups of cells that are connected together through their topology. + +.. doxygenclass:: vtkm::filter::connected_components::CellSetConnectivity + :members: + +Classification Field on Image Data +---------------------------------------- + +.. index:: + double: connected components; image + double: connected components; field + double: connected components; filter + +The :class:`vtkm::filter::connected_components::ImageConnectivity` filter finds groups of points that have the same field value and are connected together through their topology. + +.. doxygenclass:: vtkm::filter::connected_components::ImageConnectivity + :members: + + +Contouring +============================== + +.. index:: double: contouring; filter + +The ``vtkm::filter::contour`` module contains filters that extract regions that match some field or spatial criteria. +Unlike :numref:`entity extraction filters (Section %s)`, the geometry will be clipped or sliced to extract the exact matching region. +(In contrast, entity extraction filters will pull unmodified points, edges, faces, or cells from the input.) + +Contour +------------------------------ + +.. index:: + double: contour; filter + double: isosurface; filter + +*Contouring* is one of the most fundamental filters in scientific visualization. +A contour is the locus where a field is equal to a particular value. +A topographic map showing curves of various elevations often used when hiking in hilly regions is an example of contours of an elevation field in 2 dimensions. +Extended to 3 dimensions, a contour gives a surface. +Thus, a contour is often called an *isosurface*. +The contouring/isosurface algorithm is implemented by :class:`vtkm::filter::contour::Contour`. + +.. doxygenclass:: vtkm::filter::contour::Contour + :members: + +:class:`vtkm::filter::contour::Contour` also inherits the following methods. + +.. doxygenfunction:: vtkm::filter::contour::AbstractContour::SetIsoValue(vtkm::Float64) + +.. doxygenfunction:: vtkm::filter::contour::AbstractContour::SetIsoValue(vtkm::Id, vtkm::Float64) + +.. doxygenfunction:: vtkm::filter::contour::AbstractContour::SetIsoValues + +.. doxygenfunction:: vtkm::filter::contour::AbstractContour::GetIsoValue + +.. doxygenfunction:: vtkm::filter::contour::AbstractContour::SetGenerateNormals + +.. doxygenfunction:: vtkm::filter::contour::AbstractContour::GetGenerateNormals + +.. doxygenfunction:: vtkm::filter::contour::AbstractContour::SetComputeFastNormals + +.. doxygenfunction:: vtkm::filter::contour::AbstractContour::GetComputeFastNormals + +.. doxygenfunction:: vtkm::filter::contour::AbstractContour::SetNormalArrayName + +.. doxygenfunction:: vtkm::filter::contour::AbstractContour::GetNormalArrayName + +.. doxygenfunction:: vtkm::filter::contour::AbstractContour::SetMergeDuplicatePoints + +.. doxygenfunction:: vtkm::filter::contour::AbstractContour::GetMergeDuplicatePoints + +.. load-example:: Contour + :file: GuideExampleProvidedFilters.cxx + :caption: Using :class:`vtkm::filter::contour::Contour`. + +Slice +------------------------------ + +.. index:: + double: slice; filter + +A slice operation intersects a mesh with a surface. +The :class:`vtkm::filter::contour::Slice` filter uses a :class:`vtkm::ImplicitFunctionGeneral` to specify an implicit surface to slice on. +A plane is a common thing to slice on, but other surfaces are available. +See Chapter \ref{chap:ImplicitFunctions} for information on implicit functions. + +.. todo:: Fix reference to implicit functions above. + +.. doxygenclass:: vtkm::filter::contour::Slice + :members: + +The :class:`vtkm::filter::contour::Slice` filter inherits from the :class:`vtkm::filter::contour::Contour`, uses its implementation to extract the slices, and several of the inherited methods are useful including :func:`vtkm::filter::contour::AbstractContour::SetGenerateNormals`, :func:`vtkm::filter::contour::AbstractContour::GetGenerateNormals`, :func:`vtkm::filter::contour::AbstractContour::SetComputeFastNormals`, :func:`vtkm::filter::contour::AbstractContour::GetComputeFastNormals`, :func:`vtkm::filter::contour::AbstractContour::SetNormalArrayName`, :func:`vtkm::filter::contour::AbstractContour::GetNormalArrayName`, :func:`vtkm::filter::contour::AbstractContour::SetMergeDuplicatePoints`, :func:`vtkm::filter::contour::AbstractContour::GetMergeDuplicatePoints`, :func:`vtkm::filter::FilterField::SetActiveCoordinateSystem`, and :func:`vtkm::filter::FilterField::GetActiveCoordinateSystemIndex`. + +Clip with Field +------------------------------ + +.. index:: + double: clip; filter + double: clip; field + single: isovolume + single: interval volume + +Clipping is an operation that removes regions from the data set based on a user-provided value or function. +The :class:`vtkm::filter::contour::ClipWithField` filter takes a clip value as an argument and removes regions where a named scalar field is below (or above) that value. +(A companion filter that discards a region of the data based on an implicit function is described later.) + +The result of :class:`vtkm::filter::contour::ClipWithField` is a volume. +If a cell has field values at its vertices that are all below the specified value, then it will be discarded entirely. +Likewise, if a cell has field values at its vertices that are all above the specified value, then it will be retained in its entirety. +If a cell has some vertices with field values below the specified value and some above, then the cell will be split into the portions above the value (which will be retained) and the portions below the value (which will be discarded). + +This operation is sometimes called an *isovolume* because it extracts the volume of a mesh that is inside the iso-region of a scalar. +This is in contrast to an *isosurface*, which extracts only the surface of that iso-value. +That said, a more appropriate name is *interval volume* as the volume is defined by a range of values, not a single "iso" value. + +:class:`vtkm::filter::contour::ClipWithField` is also similar to a threshold operation, which extracts cells based on the value of field. +The difference is that threshold will either keep or remove entire cells based on the field values whereas clip with carve cells that straddle the valid regions. +See :secref:`provided-filters:Threshold` for information on threshold extraction. + +.. doxygenclass:: vtkm::filter::contour::ClipWithField + :members: + +.. load-example:: ClipWithField + :file: GuideExampleProvidedFilters.cxx + :caption: Using :class:`vtkm::filter::contour::ClipWithField`. + +Clip with Implicit Function +------------------------------ + +.. index:: + double: clip; filter + double: clip; implicit function + +The :class:`vtkm::filter::contour::ClipWithImplicitFunction` function takes an implicit function and removes all parts of the data that are inside (or outside) that function. +See Chapter \ref{chap:ImplicitFunctions} for more detail on how implicit functions are represented in |VTKm|. +A companion filter that discards a region of the data based on the value of a scalar field is described in :secref:`provided-filters:Extract Geometry`. + +.. todo:: Fix above reference to implicit function chapter. + +The result of :class:`vtkm::filter::contour::ClipWithImplicitFunction` is a volume. +If a cell has its vertices positioned all outside the implicit function, then it will be discarded entirely. +Likewise, if a cell its vertices all inside the implicit function, then it will be retained in its entirety. +If a cell has some vertices inside the implicit function and some outside, then the cell will be split into the portions inside (which will be retained) and the portions outside (which will be discarded). + +.. doxygenclass:: vtkm::filter::contour::ClipWithImplicitFunction + :members: + +In the example provided below the :class:`vtkm::Sphere` implicit function is used. +This function evaluates to a negative value if points from the original dataset occur within the sphere, evaluates to 0 if the points occur on the surface of the sphere, and evaluates to a positive value if the points occur outside the sphere. + +.. load-example:: ClipWithImplicitFunction + :file: GuideExampleProvidedFilters.cxx + :caption: Using :class:`vtkm::filter::contour::ClipWithImplicitFunction`. + + +Density Estimation +============================== + +.. index:: + double: density; filter + +Density estimation takes a collection of samples and estimates the density of the samples in each part of the domain (or estimate the probabilty that a sample would be at a location in the domain). +The domain of samples could be a physical space, such as with particle density, or in an abstract place, such as with a histogram. +The ``vtkm::filter::density_estimate`` module contains filters that estimate density in a variety of ways. + +.. todo:: Entropy, NDEntropy, and NDHistogram filters are not documented. + +Histogram +------------------------------ + +.. index:: + double: histogram; filter + double: density; histogram + +The :class:`vtkm::filter::density_estimate::Histogram` filter computes a histogram of a given scalar field. + +.. doxygenclass:: vtkm::filter::density_estimate::Histogram + :members: + +Particle Density +------------------------------ + +|VTKm| provides multiple filters to take as input a collection of points and build a regular mesh containing an estimate of the density of particles in that space. These filters inhert from :class:`vtkm::filter::density_estimate::ParticleDensityBase`. + +.. doxygenclass:: vtkm::filter::density_estimate::ParticleDensityBase + :members: + +Nearest Grid Point +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. index:: + triple: particle; density; nearest grid point + +The :class:`vtkm::filter::density_estimate::ParticleDensityNearestGridPoint` filter defines a 3D grid of bins. +It then takes from the input a collection of particles, identifies which bin each particle lies in, and sums some attribute from a field of the input (or the particles can simply be counted). + +.. doxygenclass:: vtkm::filter::density_estimate::ParticleDensityNearestGridPoint + :members: + +Cloud in Cell +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. index:: + triple: particle; density; cloud in cell + +The :class:`vtkm::filter::density_estimate::ParticleDensityCloudInCell` filter defines a 3D grid of bins. +It then takes from the input a collection of particles, identifies which bin each particle lies in, and then redistributes each particle's attribute to the 8 vertices of the containing bin. +The filter then sums up all the contributions of particles for each bin in the grid. + +.. doxygenclass:: vtkm::filter::density_estimate::ParticleDensityCloudInCell + :members: + +Statistics +------------------------------ + +Simple descriptive statics for data in field arrays can be computed with :class:`vtkm::filter::density_estimate::Statistics`. + +.. doxygenclass:: vtkm::filter::density_estimate::Statistics + :members: + +Entity Extraction +============================== + +.. index:: + double: filter; entity extraction + +|VTKm| contains a collection of filters that extract a portion of one :class:`vtkm::cont::DataSet` and construct a new :class:`vtkm::cont::DataSet` based on that portion of the geometry. +These filters are collected in the ``vtkm::filter::entity_extraction`` module. + +External Faces +------------------------------ + +.. index:: + double: external faces; filter + single: face; external + +:class:`vtkm::filter::entity_extraction::ExternalFaces` is a filter that extracts all the external faces from a polyhedral data set. +An external face is any face that is on the boundary of a mesh. +Thus, if there is a hole in a volume, the boundary of that hole will be considered external. +More formally, an external face is one that belongs to only one cell in a mesh. + +.. doxygenclass:: vtkm::filter::entity_extraction::ExternalFaces + :members: + +Extract Geometry +------------------------------ + +.. index:: + double: extract geometry; filter + +The :class:`vtkm::filter::entity_extraction::ExtractGeometry` filter extracts all of the cells in a :class:`vtkm::cont::DataSet` that is inside or outside of an implicit function. +Implicit functions are described in Chapter \ref{chap:ImplicitFunctions}. +They define a function in 3D space that follow a geometric shape. +The inside of the implicit function is the region of negative values. + +.. todo:: Fix above reference to implicit function chapter. + +.. doxygenclass:: vtkm::filter::entity_extraction::ExtractGeometry + :members: + +Extract Points +------------------------------ + +.. index:: + double: extract points; filter + +The :class:`vtkm::filter::entity_extraction::ExtractPoints` filter behaves the same as :class:`vtkm::filter::entity_extraction::ExtractGeometry` (:numref:`Section %s`) except that the geometry is converted into a point cloud. +The filter determines whether each point is inside or outside the implicit function and passes only those that match the criteria. +The cell information of the input is thrown away and replaced with a cell set of "vertex" cells, one per point. + +.. doxygenclass:: vtkm::filter::entity_extraction::ExtractPoints + :members: + +Extract Structured +------------------------------ + +.. index:: + double: extract structured; filter + +:class:`vtkm::filter::entity_extraction::ExtractStructured` is a filter that extracts a volume of interest (VOI) from a structured data set. +In addition the filter is able to subsample the VOI while doing the extraction. +The input and output of this filter are a structured data sets. + +.. doxygenclass:: vtkm::filter::entity_extraction::ExtractStructured + :members: + +.. todo:: Document vtkm::RangeId and vtkm::RangeId3 (in advanced types chapter). + +Ghost Cell Removal +------------------------------ + +.. index:: + double: ghost cell; filter + single: ghost cell; remove + single: blanked cell; remove + +The :class:`vtkm::filter::entity_extraction::GhostCellRemove` filter is used to remove cells from a data set according to a cell centered field that specifies whether a cell is a regular cell or a ghost cell. +By default, the filter will get the ghost cell information that is registered in the input :class:`vtkm::cont::DataSet`, but it also possible to specify an arbitrary field for this purpose. + +.. todo:: Better document how ghost cells work in |VTKm| (somewhere). + +.. doxygenclass:: vtkm::filter::entity_extraction::GhostCellRemove + :members: + +Threshold +------------------------------ + +.. index:: + double: threshold; filter + +A threshold operation removes topology elements from a data set that do not meet a specified criterion. +The :class:`vtkm::filter::entity_extraction::Threshold` filter removes all cells where the a field is outside a range of values. + +Note that :class:`vtkm::filter::entity_extraction::Threshold` either passes an entire cell or discards an entire cell. +This can consequently lead to jagged surfaces at the interface of the threshold caused by the shape of cells that jut inside or outside the removed region. +See :secref:`provided-filters:Clip with Field` for a clipping filter that will clip off a smooth region of the mesh. + +.. doxygenclass:: vtkm::filter::entity_extraction::Threshold + :members: + + +Field Conversion +============================== + +.. index:: + double: filter; field conversion + +Field conversion modifies a field of a :class:`vtkm::cont::DataSet` to have roughly equivalent values but with a different structure. +These filters allow the field to be used in places where they otherwise would not be applicable. + +Cell Average +------------------------------ + +.. index:: + double: cell average; filter + +:class:`vtkm::filter::field_conversion::CellAverage` is the cell average filter. +It will take a data set with a collection of cells and a field defined on the points of the data set and create a new field defined on the cells. +The values of this new derived field are computed by averaging the values of the input field at all the incident points. +This is a simple way to convert a point field to a cell field. + +.. doxygenclass:: vtkm::filter::field_conversion::CellAverage + :members: + +Point Average +------------------------------ + +.. index:: + double: point average; filter + +:class:`vtkm::filter::field_conversion::PointAverage` is the point average filter. +It will take a data set with a collection of cells and a field defined on the cells of the data set and create a new field defined on the points. +The values of this new derived field are computed by averaging the values of the input field at all the incident cells. +This is a simple way to convert a cell field to a point field. + +.. doxygenclass:: vtkm::filter::field_conversion::PointAverage + :members: + + +Field Transform +============================== + +.. index:: + double: filter; field transform + +|VTKm| provides multiple filters to convert fields through some mathematical relationship. + +Composite Vectors +------------------------------ + +.. index:: + double: filter; composite vectors + +The :class:`vtkm::filter::field_transform::CompositeVectors` filter allows you to group multiple scalar fields into a single vector field. +This is convenient when importing data from a souce that stores vector components in separate arrays. + +.. doxygenclass:: vtkm::filter::field_transform::CompositeVectors + :members: + +Cylindrical Coordinate System Transform +---------------------------------------- + +.. index:: + double: filter; cylindrical coordinate system transform + single: coordinate system transform; cylindrical + +The :class:`vtkm::filter::field_transform::CylindricalCoordinateTransform` filter is a coordinate system transformation. +The filter will take a data set and transform the points of the coordinate system. +By default, the filter will transform the coordinates from a Cartesian coordinate system to a cylindrical coordinate system. +The order for cylindrical coordinates is :math:`(R, \theta, Z)`. +The output coordinate system will be set to the new computed coordinates. + +.. doxygenclass:: vtkm::filter::field_transform::CylindricalCoordinateTransform + :members: + +Field to Colors +------------------------------ + +.. index:: + double: filter; field to colors + +The :class:`vtkm::filter::field_transform::FieldToColors` filter takes a field in a data set, looks up each value in a color table, and writes the resulting colors to a new field. +The color to be used for each field value is specified using a :class:`vtkm::cont::ColorTable` object. +:class:`vtkm::cont::ColorTable` objects are also used with |VTKm|'s rendering module and are described in Section~\ref{sec:ColorTables}. + +.. todo:: Fix above reference to color tables section. + +:class:`vtkm::filter::field_transform::FieldToColors` has three modes it can use to select how it should treat the input field. +These input modes are contained in :enum:`vtkm::filter::field_transform::FieldToColors::InputMode`. +Additionally, :class:`vtkm::filter::field_transform::FieldToColors` has different modes in which it can represent colors in its output. +These output modes are contained in :enum:`vtkm::filter::field_transform::FieldToColors::OutputMode`. + +.. doxygenclass:: vtkm::filter::field_transform::FieldToColors + :members: + +Generate Ids +------------------------------ + +.. index:: + double: generate ids; filter + +The :class:`vtkm::filter::field_transform::GenerateIds` filter creates point and/or cell fields that mimic the identifier for the respective element. + +.. doxygenclass:: vtkm::filter::field_transform::GenerateIds + :members: + +Log Values +------------------------------ + +.. index:: + double: log; filter + +The :class:`vtkm::filter::field_transform::LogValues` filter can be used to take the logarithm of all values in a field. +The filter is able to take the logarithm to a number of predefined bases identified by :enum:`vtkm::filter::field_transform::LogValues::LogBase`. + +.. doxygenclass:: vtkm::filter::field_transform::LogValues + :members: + +Point Elevation +------------------------------ + +.. index:: + double: point elevation; filter + double: elevation; filter + +The :class:`vtkm::filter::field_transform::PointElevation` filter computes the "elevation" of a field of point coordinates in space. +:numref:`ex:PointElevation` gives a demonstration of the elevation filter. + + +.. doxygenclass:: vtkm::filter::field_transform::PointElevation + :members: + +Point Transform +------------------------------ + +.. index:: + double: point transform; filter + double: transform; filter + +The :class:`vtkm::filter::field_transform::PointTransform` filter performs affine transforms is the point transform filter. + +.. doxygenclass:: vtkm::filter::field_transform::PointTransform + :members: + +Spherical Coordinate System Transform +---------------------------------------- + +.. index:: + double: filter; spherical coordinate system transform + single: coordinate system transform; spherical + +The :class:`vtkm::filter::field_transform::SphericalCoordinateTransform` filter is a coordinate system transformation. +The filter will take a data set and transform the points of the coordinate system. +By default, the filter will transform the coordinates from a Cartesian coordinate system to a spherical coordinate system. +The order for spherical coordinates is :math:`(R, \theta, \phi)` where :math:`R` is the radius, :math:`\theta` is the azimuthal angle and :math:`\phi` is the polar angle. +The output coordinate system will be set to the new computed coordinates. + +.. doxygenclass:: vtkm::filter::field_transform::SphericalCoordinateTransform + :members: + +Warp +------------------------------ + +.. index:: + double: warp; filter + +The :class:`vtkm::filter::field_transform::Warp` filter modifies points in a :class:`vtkm::cont::DataSet` by moving points along scaled direction vectors. +By default, the :class:`vtkm::filter::field_transform::Warp` filter modifies the coordinate system and writes its results to the coordiante system. +A vector field can be selected as directions, or a constant direction can be specified. +A constant direction is particularly useful for generating a carpet plot. +A scalar field can be selected to scale the displacement, and a constant scale factor adjustment can be specified. + +.. doxygenclass:: vtkm::filter::field_transform::Warp + :members: + + +Flow Analysis +============================== + +.. index:: flow + +Flow visualization is used to analyze vector fields that represent the movement of a fluid. +The basic operation of most flow visualization algorithms is particle advection, which traces the path a particle would take given the direction and speed dictated by the vector field. +There are multiple ways in which to represent flow in this manner, and consequently |VTKm| contains several filters that trace streams in different ways. +These filters inherit from :class:`vtkm::filter::flow::FilterParticleAdvection`, which provides several important methods. + +.. doxygenclass:: vtkm::filter::flow::FilterParticleAdvection + :members: + +Flow filters operate either on a "steady state" flow that does not change or on an "unsteady state" flow that is continually changing over time. +An unsteady state filter must be executed multiple times for subsequent time steps. +The filter operates with data from two adjacent time steps. +This is managed by the :class:`vtkm::filter::flow::FilterParticleAdvectionUnsteadyState` superclass. + +Streamlines +------------------------------ + +.. index:: + double: streamlines; filter + single: flow; streamlines + +*Streamlines* are a powerful technique for the visualization of flow fields. +A streamline is a curve that is parallel to the velocity vector of the flow field. +Individual streamlines are computed from an initial point location (seed) using a numerical +method to integrate the point through the flow field. + +.. doxygenclass:: vtkm::filter::flow::Streamline + :members: + +The :class:`vtkm::filter::flow::Streamline` filter also uses several inherited methods: :func:`vtkm::filter::flow::FilterParticleAdvection::SetSeeds`, :func:`vtkm::filter::flow::FilterParticleAdvection::SetStepSize`, and :func:`vtkm::filter::flow::FilterParticleAdvection::SetNumberOfSteps`. + +.. load-example:: Streamlines + :file: GuideExampleProvidedFilters.cxx + :caption: Using :class:`vtkm::filter::flow::Streamline`. + +Pathlines +------------------------------ + +.. index:: + double: pathlines; filter + single: flow; pathlines + +*Pathlines* are the analog to streamlines for time varying vector fields. +Individual pathlines are computed from an initial point location (seed) using a numerical method to integrate the point through the flow field. + +This filter requires two data sets as input, which represent the data for two sequential time steps. +The "Previous" data set, which marks the data at the earlier time step, is passed into the filter throught the standard ``Execute`` method. +The "Next" data set, which marks the data at the later time step, is specified as state to the filter using methods. + +.. doxygenclass:: vtkm::filter::flow::Pathline + :members: + +As an unsteady state flow filter, :class:`vtkm::filter::flow::Pathline` must be executed multiple times for subsequent time steps. +The filter operates with data from two adjacent time steps. +This is managed by the :class:`vtkm::filter::flow::FilterParticleAdvectionUnsteadyState` superclass. + +The :class:`vtkm::filter::flow::Pathline` filter uses several other inherited methods: :func:`vtkm::filter::flow::FilterParticleAdvectionUnsteadyState::SetPreviousTime`, :func:`vtkm::filter::flow::FilterParticleAdvectionUnsteadyState::SetNextTime`, :func:`vtkm::filter::flow::FilterParticleAdvectionUnsteadyState::SetNextDataSet`, :func:`vtkm::filter::flow::FilterParticleAdvection::SetSeeds`, :func:`vtkm::filter::flow::FilterParticleAdvection::SetStepSize`, and :func:`vtkm::filter::flow::FilterParticleAdvection::SetNumberOfSteps`. + +.. load-example:: Pathlines + :file: GuideExampleProvidedFilters.cxx + :caption: Using :class:`vtkm::filter::flow::Pathline`. + +Stream Surface +------------------------------ + +.. index:: + double: stream surface; filter + single: flow; stream surface + +A *stream surface* is defined as a continuous surface that is everywhere tangent to a specified vector field. +The :class:`vtkm::filter::flow::StreamSurface` filter computes a stream surface from a set of input points and the vector field of the input data set. +The stream surface is created by creating streamlines from each input point and then connecting adjacent streamlines with a series of triangles. + +.. doxygenclass:: vtkm::filter::flow::StreamSurface + :members: + +.. load-example:: StreamSurface + :file: GuideExampleProvidedFilters.cxx + :caption: Using :class:`vtkm::filter::flow::StreamSurface`. + +Lagrangian Coherent Structures +------------------------------ + +.. index:: + double: FTLE; filter + double: Lagrangian coherent structures; filter + see: LCS; Lagrangian coherent structures + see: finite time Lyapunov exponent; FTLE + +Lagrangian coherent structures (LCS) are distinct structures present in a flow field that have a major influence over nearby trajectories over some interval of time. +Some of these structures may be sources, sinks, saddles, or vortices in the flow field. +Identifying Lagrangian coherent structures is part of advanced flow analysis and is an important part of studying flow fields. +These structures can be studied by calculating the finite time Lyapunov exponent (FTLE) for a flow field at various locations, usually over a regular grid encompassing the entire flow field. +If the provided input dataset is structured, then by default the points in this data set will be used as seeds for advection. +The :class:`vtkm::filter::flow::LagrangianStructures` filter is used to compute the FTLE of a flow field. + +.. doxygenclass:: vtkm::filter::flow::LagrangianStructures + :members: + + +Geometry Refinement +============================== + +.. index:: geometry refinement + +Geometry refinement modifies the geometry of a :class:`vtkm::cont::DataSet`. +It might add, change, or remove components of the structure, but the general representation will be the same. + +Convert to a Point Cloud +------------------------------ + +.. index:: + double: convert to point cloud; filter + single: meshless data + +Data in a :class:`vtkm::cont::DataSet` is typically connected together by cells in a mesh structure. +However, it is sometimes the case where data are simply represented as a cloud of unconnected points. +These meshless data sets are best represented in a :class:`vtkm::cont::DataSet` by a collection of "vertex" cells. + +The :class:`vtkm::filter::geometry_refinement::ConvertToPointCloud` filter converts a data to a point cloud. +It does this by throwing away any existing cell set and replacing it with a collection of vertex cells, one per point. +:class:`vtkm::filter::geometry_refinement::ConvertToPointCloud` is useful to add a cell set to a :class:`vtkm::cont::DataSet` that has points but no cells. +It is also useful to treat data as a collection of sample points rather than an interconnected mesh. + +.. doxygenclass:: vtkm::filter::geometry_refinement::ConvertToPointCloud + :members: + +Shrink +------------------------------ + +.. index:: + double: shrink; filter + single: exploded view + +The :class:`vtkm::filter::geometry_refinement::Shrink` independently reduces the size of each class. +Rather than uniformly reduce the size of the whole data set (which can be done with :class:`vtkm::filter::field_transform::PointTransform`), this filter separates the cells from each other and shrinks them around their centroid. +This is useful for making an "exploded view" of the data where the facets of the data are moved away from each other to see inside. + +.. doxygenclass:: vtkm::filter::geometry_refinement::Shrink + :members: + +Split Sharp Edges +------------------------------ + +.. index:: + double: split sharp edges; filter + +The :class:`vtkm::filter::geometry_refinement::SplitSharpEdges` filter splits sharp manifold edges where the feature angle between the adjacent surfaces are larger than a threshold value. +This is most useful to preserve sharp edges when otherwise applying smooth shading during rendering. + +.. doxygenclass:: vtkm::filter::geometry_refinement::SplitSharpEdges + :members: + +Tetrahedralize +------------------------------ + +.. index:: + double: tetrahedralize; filter + +The :class:`vtkm::filter::geometry_refinement::Tetrahedralize` filter converts all the polyhedra in a :class:`vtkm::cont::DataSet` into tetrahedra. + +.. doxygenclass:: vtkm::filter::geometry_refinement::Tetrahedralize + :members: + +Triangulate +------------------------------ + +.. index:: + double: triangulate; filter + +The :class:`vtkm::filter::geometry_refinement::Triangulate` filter converts all the polyhedra in a :class:`vtkm::cont::DataSet` into tetrahedra. + +.. doxygenclass:: vtkm::filter::geometry_refinement::Triangulate + :members: + +Tube +------------------------------ + +.. index:: + double: tube; filter + +The :class:`vtkm::filter::geometry_refinement::Tube` filter generates a tube around each line and polyline in the input data set. + +.. doxygenclass:: vtkm::filter::geometry_refinement::Tube + :members: + +.. load-example:: Tube + :file: GuideExampleProvidedFilters.cxx + :caption: Using :class:`vtkm::filter::geometry_refinement::Tube`. + +Vertex Clustering +------------------------------ + +.. index:: + double: vertex clustering; filter + double: surface simplification; filter + +The :class:`vtkm::filter::geometry_refinement::VertexClustering` filter simplifies a polygonal mesh. +It does so by dividing space into a uniform grid of bin and then merges together all points located in the same bin. +The smaller the dimensions of this binning grid, the fewer polygons will be in the output cells and the coarser the representation. +This surface simplification is an important operation to support :index:`level of detail` (:index:`LOD`) rendering in visualization applications. + +.. doxygenclass:: vtkm::filter::geometry_refinement::VertexClustering + :members: + +.. load-example:: VertexClustering + :file: GuideExampleProvidedFilters.cxx + :caption: Using :class:`vtkm::filter::geometry_refinement::VertexClustering`. + + +Mesh Information +============================== + +.. index:: mesh information + +|VTKm| provides several filters that derive information about the structure of the geometry. +This can be information about the shape of cells or their connections. + +Cell Size Measurements +------------------------------ + +.. index:: + double: cell measures; filter + +The :class:`vtkm::filter::mesh_info::CellMeasures` filter integrates the size of each cell in a mesh and reports the size in a new cell field. + +.. doxygenclass:: vtkm::filter::mesh_info::CellMeasures + :members: + +By default, :class:`vtkm::filter::mesh_info::CellMeasures` will compute the measures of all types of cells. +It is sometimes desirable to limit the types of cells to measure to prevent the resulting field from mixing values of different units. +The appropriate measure to compute can be specified with the :enum:`vtkm::filter::mesh_info::IntegrationType` enumeration. + +.. doxygenenum:: vtkm::filter::mesh_info::IntegrationType + +Ghost Cell Classification +------------------------------ + +.. index:: + double: ghost cell classification; filter + single: ghost cell; classify + +The :class:`vtkm::filter::mesh_info::GhostCellClassify` filter determines which cells should be considered ghost cells in a structured data set. +The ghost cells are expected to be on the border. + +.. todo:: Document ``vtkm::CellClassification``. + +.. doxygenclass:: vtkm::filter::mesh_info::GhostCellClassify + :members: + +Mesh Quality Metrics +------------------------------ + +.. index:: + double: mesh quality; filter + single: mesh information; quality + +|VTKm| provides several filters to compute metrics about the mesh quality. +These filters produce a new cell field that holds a given metric for the shape of the cell. +The metrics for this filter come from the Verdict library, and +full mathematical descriptions for each metric can be found in the Verdict +documentation (Sandia technical report SAND2007-1751, +https://coreform.com/papers/verdict_quality_library.pdf). + +.. doxygenclass:: vtkm::filter::mesh_info::MeshQualityArea + :members: + +.. doxygenclass:: vtkm::filter::mesh_info::MeshQualityAspectGamma + :members: + +.. doxygenclass:: vtkm::filter::mesh_info::MeshQualityAspectRatio + :members: + +.. doxygenclass:: vtkm::filter::mesh_info::MeshQualityCondition + :members: + +.. doxygenclass:: vtkm::filter::mesh_info::MeshQualityDiagonalRatio + :members: + +.. doxygenclass:: vtkm::filter::mesh_info::MeshQualityDimension + :members: + +.. doxygenclass:: vtkm::filter::mesh_info::MeshQualityJacobian + :members: + +.. doxygenclass:: vtkm::filter::mesh_info::MeshQualityMaxAngle + :members: + +.. doxygenclass:: vtkm::filter::mesh_info::MeshQualityMaxDiagonal + :members: + +.. doxygenclass:: vtkm::filter::mesh_info::MeshQualityMinAngle + :members: + +.. doxygenclass:: vtkm::filter::mesh_info::MeshQualityMinDiagonal + :members: + +.. doxygenclass:: vtkm::filter::mesh_info::MeshQualityOddy + :members: + +.. doxygenclass:: vtkm::filter::mesh_info::MeshQualityRelativeSizeSquared + :members: + +.. doxygenclass:: vtkm::filter::mesh_info::MeshQualityScaledJacobian + :members: + +.. doxygenclass:: vtkm::filter::mesh_info::MeshQualityShape + :members: + +.. doxygenclass:: vtkm::filter::mesh_info::MeshQualityShapeAndSize + :members: + +.. doxygenclass:: vtkm::filter::mesh_info::MeshQualityShear + :members: + +.. doxygenclass:: vtkm::filter::mesh_info::MeshQualitySkew + :members: + +.. doxygenclass:: vtkm::filter::mesh_info::MeshQualityStretch + :members: + +.. doxygenclass:: vtkm::filter::mesh_info::MeshQualityTaper + :members: + +.. doxygenclass:: vtkm::filter::mesh_info::MeshQualityVolume + :members: + +.. doxygenclass:: vtkm::filter::mesh_info::MeshQualityWarpage + :members: + +The :class:`vtkm::filter::mesh_info::MeshQuality` filter consolidates all of these metrics into a single filter. +The metric to compute is selected with the :func:`vtkm::filter::mesh_info::MeshQuality::SetMetric()`. + +.. doxygenclass:: vtkm::filter::mesh_info::MeshQuality + :members: + +The metric to compute is identified using the :enum:`vtkm::filter::mesh_info::CellMetric` enum. + +.. doxygenenum:: vtkm::filter::mesh_info::CellMetric + + +Multi-Block +============================== + +.. index:: multi-block + +Data with multiple blocks are stored in :class:`vtkm::cont::PartitionedDataSet` objects. +Most |VTKm| filters operate correctly on :class:`vtkm::cont::PartitionedDataSet` just like they do with :class:`vtkm::cont::DataSet`. +However, there are some filters that are designed with operations specific to multi-block datasets. + +AMR Arrays +------------------------------ + +.. index:: + double: AMR arrays; filter + single: AMR; arrays + +An AMR mesh is a :class:`vtkm::cont::PartitionedDataSet` with a special structure in the partitions. +Each partition has a :class:`vtkm::cont::CellSetStructured` cell set. +The partitions form a hierarchy of grids where each level of the hierarchy refines the one above. + +:class:`vtkm::cont::PartitionedDataSet` does not explicitly store the structure of an AMR grid. +The :class:`vtkm::filter::multi_block::AmrArrays` filter determines the hierarchical structure of the AMR partitions and stores information about them in cell field arrays on each partition. + +.. doxygenclass:: vtkm::filter::multi_block::AmrArrays + :members: + +.. didyouknow:: + The names of the generated field arrays arrays (e.g. ``vtkAmrLevel``) are chosen to be compatible with the equivalent arrays in VTK. + This is why they use the prefix of "vtk" instead of "vtkm". + Likewise, the flags used for ``vtkGhostType`` are compatible with VTK. + + +Resampling +============================== + +All data in :class:`vtkm::cont::DataSet` objects are discrete representations. +It is sometimes necessary to resample this data in different ways. + +Histogram Sampling +------------------------------ + +.. index:: + double: histogram sampling; filter + +The :class:`vtkm::filter::resampling::HistSampling` filter randomly samples the points of an input data set. +The sampling is random but adaptive to preserve rare field value points. + +.. doxygenclass:: vtkm::filter::resampling::HistSampling + :members: + +Probe +------------------------------ + +.. index:: + double: probe; filter + +The :class:`vtkm::filter::resampling::Probe` filter maps the fields of one :class:`vtkm::cont::DataSet` onto another. +This is useful for redefining meshes as well as comparing field data from two data sets with different geometries. + +.. doxygenclass:: vtkm::filter::resampling::Probe + :members: + + +Vector Analysis +============================== + +.. index:: + single: vector analysis + +|VTKm|'s vector analysis filters compute operations on fields related to vectors (usually in 3-space). + +Cross Product +------------------------------ + +.. index:: + double: cross product; filter + +The :class:`vtkm::filter::vector_analysis::CrossProduct` filter computes the cross product of two vector fields for every element in the input data set. +The cross product filter computes (PrimaryField × SecondaryField). +The cross product computation works for either point or cell centered vector fields. + +.. doxygenclass:: vtkm::filter::vector_analysis::CrossProduct + :members: + +Dot Product +------------------------------ + +.. index:: + double: dot product; filter + +The :class:`vtkm::filter::vector_analysis::DotProduct` filter computes the dot product of two vector fields for every element in the input data set. +The dot product filter computes (PrimaryField . SecondaryField). +The dot product computation works for either point or cell centered vector fields. + +.. doxygenclass:: vtkm::filter::vector_analysis::DotProduct + :members: + +Gradients +------------------------------ + +.. index:: + double: gradients; filter + single: point gradients + single: cell gradients + +The :class:`vtkm::filter::vector_analysis::Gradient` filter estimates the gradient of a point based input field for every element in the input data set. +The gradient computation can either generate cell center based gradients, which are fast but less accurate, or more accurate but slower point based gradients. +The default for the filter is output as cell centered gradients, but can be changed by using the :func:`vtkm::filter::vector_analysis::Gradient::SetComputePointGradient` method. +The default name for the output fields is "Gradients", but that can be overridden as always using the :func:`vtkm::filter::vector_analysis::Gradient::SetOutputFieldName` method. + +.. doxygenclass:: vtkm::filter::vector_analysis::Gradient + :members: + +Surface Normals +------------------------------ + +.. index:: + double: surface normals; filter + single: normals + +The :class:`vtkm::filter::vector_analysis::SurfaceNormals` filter computes the surface normals of a polygonal data set at its points and/or cells. +The filter takes a data set as input and by default, uses the active coordinate system to compute the normals. + +.. doxygenclass:: vtkm::filter::vector_analysis::SurfaceNormals + :members: + +Vector Magnitude +------------------------------ + +.. index:: + double: vector magnitude; filter + single: magnitude + +The :class:`vtkm::filter::vector_analysis::VectorMagnitude` filter takes a field comprising vectors and computes the magnitude for each vector. +The vector field is selected as usual with the :func:`vtkm::filter::vector_analysis::VectorMagnitude::SetActiveField` method. +The default name for the output field is ``magnitude``, but that can be overridden as always using the :func:`vtkm::filter::vector_analysis::VectorMagnitude::SetOutputFieldName` method. + +.. doxygenclass:: vtkm::filter::vector_analysis::VectorMagnitude + :members: + +ZFP Compression +============================== + +.. index:: + double: zfp; filter + single: filter; compression; + single: compression; zfp + +:class:`vtkm::filter::zfp::ZFPCompressor1D`, :class:`vtkm::filter::zfp::ZFPCompressor2D`, and :class:`vtkm::filter::zfp::ZFPCompressor3D` are a set of filters that take a 1D, 2D, and 3D field, respectively, and compresses the values using the compression algorithm ZFP. + The field is selected as usual with the :func:`vtkm::filter::zfp::ZFPCompressor3D::SetActiveField()` method. + The rate of compression is set using :func:`vtkm::filter::zfp::ZFPCompressor3D::SetRate()`. + The default name for the output field is ``compressed``. + +.. doxygenclass:: vtkm::filter::zfp::ZFPCompressor1D + :members: + +.. doxygenclass:: vtkm::filter::zfp::ZFPCompressor2D + :members: + +.. doxygenclass:: vtkm::filter::zfp::ZFPCompressor3D + :members: + +:class:`vtkm::filter::zfp::ZFPDecompressor1D`, :class:`vtkm::filter::zfp::ZFPDecompressor2D`, and :class:`vtkm::filter::zfp::ZFPDecompressor3D` are a set of filters that take a compressed 1D, 2D, and 3D field, respectively, and decompress the values using the compression algorithm ZFP. + The field is selected as usual with the :func:`vtkm::filter::zfp::ZFPDecompressor3D::SetActiveField()` method. + The rate of compression is set using :func:`vtkm::filter::zfp::ZFPDecompressor3D::SetRate()`. + The default name for the output field is ``decompressed``. + +.. doxygenclass:: vtkm::filter::zfp::ZFPDecompressor1D + :members: + +.. doxygenclass:: vtkm::filter::zfp::ZFPDecompressor2D + :members: + +.. doxygenclass:: vtkm::filter::zfp::ZFPDecompressor3D + :members: diff --git a/docs/users-guide/quick-start.rst b/docs/users-guide/quick-start.rst index 1d3858ac6..ec9db4384 100644 --- a/docs/users-guide/quick-start.rst +++ b/docs/users-guide/quick-start.rst @@ -27,11 +27,8 @@ The ``Initialize`` function is defined in the :file:`vtkm/cont/Initialize.h` hea :file: VTKmQuickStart.cxx :caption: Initializing |VTKm|. -.. todo:: Uncomment and add cross reference. - -.. - ``Initialize`` has many options to customize command line argument processing. - See Chapter \ref{chap:Initialization} for more details. +``Initialize`` has many options to customize command line argument processing. +See :chapref:`initialization:Initialization` for more details. .. didyouknow:: Don't have access to ``argc`` and ``argv``? @@ -52,7 +49,7 @@ These files have a :file:`.vtk` extension. VTK legacy files can be read using the :class:`vtkm::io::VTKDataSetReader` object, which is declared in the :file:`vtkm/io/VTKDataSetReader.h` header file. The object is constructed with a string specifying the filename (which for this example we will get from the command line). -The data is then read in by calling the :member:`vtkm::io::VTKDataSetReader::ReadDataSet` method. +The data is then read in by calling the :func:`vtkm::io::VTKDataSetReader::ReadDataSet` method. .. load-example:: VTKmQuickStartReadFile :file: VTKmQuickStart.cxx @@ -133,9 +130,9 @@ In our case we only have one ``DataSet`` to render, so we simply create a single The second step in setting up a render is to create a *view*. The view comprises the aforementioned scene, a *mapper*, which describes how the data are to be rendered, and a *canvas*, which holds the image buffer and other rendering context. The view is created in :exlineref:`VTKmQuickStartRender:view`. -The image generation is then performed by calling :member:`vtkm::rendering::View::Paint` on the view object (:exlineref:`VTKmQuickStartRender:paint`). +The image generation is then performed by calling :func:`vtkm::rendering::View::Paint` on the view object (:exlineref:`VTKmQuickStartRender:paint`). However, the rendering done by |VTKm|'s rendering classes is performed offscreen, which means that the result does not appear on your computer's monitor. -The easiest way to see the image is to save it to an image file using the :member:`vtkm::rendering::View::SaveAs` method (:exlineref:`VTKmQuickStartRender:save`). +The easiest way to see the image is to save it to an image file using the :func:`vtkm::rendering::View::SaveAs` method (:exlineref:`VTKmQuickStartRender:save`). ------------------------------ diff --git a/docs/users-guide/rendering.rst b/docs/users-guide/rendering.rst new file mode 100644 index 000000000..2c6406354 --- /dev/null +++ b/docs/users-guide/rendering.rst @@ -0,0 +1,661 @@ +============================== +Rendering +============================== + +.. index:: rendering + +Rendering, the generation of images from data, is a key component to visualization. +To assist with rendering, |VTKm| provides a rendering package to produce imagery from data, which is located in the ``vtkm::rendering`` namespace. + +The rendering package in |VTKm| is not intended to be a fully featured +rendering system or library. Rather, it is a lightweight rendering package +with two primary use cases: + + * New users getting started with |VTKm| need a "quick and dirty" render method to see their visualization results. + * In situ visualization that integrates |VTKm| with a simulation or other data-generation system might need a lightweight rendering method. + +Both of these use cases require just a basic rendering platform. +Because |VTKm| is designed to be integrated into larger systems, it does not aspire to have a fully featured rendering system. + +.. didyouknow:: + |VTKm|'s big sister toolkit VTK is already integrated with |VTKm| and has its own fully featured rendering system. + If you need more rendering capabilities than what |VTKm| provides, you can leverage VTK instead. + + +------------------------------ +Scenes and Actors +------------------------------ + +.. index:: + double: rendering; actor + +The primary intent of the rendering package in |VTKm| is to visually display the data that is loaded and processed. +Data are represented in |VTKm| by :class:`vtkm::cont::DataSet` objects, which are described in :chapref:`dataset:Data Sets`. +They are also the object created from :chapref:`io:File I/O` and :chapref:`running-filters:Running Filters`. + +To render a :class:`vtkm::cont::DataSet`, the data are wrapped in a +:class:`vtkm::rendering::Actor` class. The :class:`vtkm::rendering::Actor` holds the +components of the :class:`vtkm::cont::DataSet` to render (a cell set, a +coordinate system, and a field). A color table can also be optionally be +specified, but a default color table will be specified otherwise. + +.. load-example:: ActorScene + :file: GuideExampleRendering.cxx + :caption: Creating an :class:`vtkm::rendering::Actor` and adding it to a :class:`vtkm::rendering::Scene`. + +.. doxygenclass:: vtkm::rendering::Actor + :members: + +.. index:: + double: rendering; scene + +:class:`vtkm::rendering::Actor` objects are collected together in an object called :class:`vtkm::rendering::Scene`. + An :class:`vtkm::rendering::Actor` is added to a :class:`vtkm::rendering::Scene` with the :func:`vtkm::rendering::Scene::AddActor` method. + +.. doxygenclass:: vtkm::rendering::Scene + :members: + +The following example demonstrates creating a :class:`vtkm::rendering::Scene` with one :class:`vtkm::rendering::Actor`. + + +------------------------------ +Canvas +------------------------------ + +.. index:: + double: rendering; canvas + +A canvas is a unit that represents the image space that is the target of the rendering. +The canvas' primary function is to manage the buffers that hold the working image data during the rendering. +The canvas also manages the context and state of the rendering subsystem. + +.. index:: + double: canvas; ray tracer + +:class:`vtkm::rendering::Canvas` is the base class of all canvas objects. +Each type of rendering system has its own canvas subclass, but currently the only rendering system provided by |VTKm| is the internal ray tracer. +The canvas for the ray tracer is :class:`vtkm::rendering::CanvasRayTracer`. +:class:`vtkm::rendering::CanvasRayTracer` is typically constructed by giving the width and height of the image to render. + +.. load-example:: Canvas + :file: GuideExampleRendering.cxx + :caption: Creating a canvas for rendering. + +.. doxygenclass:: vtkm::rendering::CanvasRayTracer + :members: + +.. doxygenclass:: vtkm::rendering::Canvas + :members: + + +------------------------------ +Mappers +------------------------------ + +.. index:: + double: rendering; mapper + +A mapper is a unit that converts data (managed by an :class:`vtkm::rendering::Actor`) and issues commands to the rendering subsystem to generate images. +All mappers in |VTKm| are a subclass of :class:`vtkm::rendering::Mapper`. +Different mappers could render different types of data in different ways. +For example, one mapper might render polygonal surfaces whereas another might render polyhedra as a translucent volume. + + +.. doxygenclass:: vtkm::rendering::Mapper + :members: + +.. + Also, different rendering systems (as established by the :class:`vtkm::rendering::Canvas`) often require different mappers. + Thus, a mapper should be picked to match both the rendering system of the :class:`vtkm::rendering::Canvas` and the data in the :class:`vtkm::rendering::Actor`. + +The following mappers are provided by |VTKm|. + +.. doxygenclass:: vtkm::rendering::MapperCylinder + :members: + +.. doxygenclass:: vtkm::rendering::MapperGlyphBase + :members: + +.. doxygenclass:: vtkm::rendering::MapperGlyphScalar + :members: + +.. doxygenclass:: vtkm::rendering::MapperGlyphVector + :members: + +.. doxygenclass:: vtkm::rendering::MapperPoint + :members: + +.. doxygenclass:: vtkm::rendering::MapperQuad + :members: + +.. doxygenclass:: vtkm::rendering::MapperRayTracer + :members: + +.. doxygenclass:: vtkm::rendering::MapperVolume + :members: + +.. doxygenclass:: vtkm::rendering::MapperWireframer + :members: + + +------------------------------ +Views +------------------------------ + +.. index:: + double: rendering; view + +A view is a unit that collects all the structures needed to perform rendering. +It contains everything needed to take a :class:`vtkm::rendering::Scene` and use a :class:`vtkm::rendering::Mapper` to render it onto a :class:`vtkm::rendering::Canvas`. +The view also annotates the image with spatial and scalar properties. + +The base class for all views is :class:`vtkm::rendering::View`, which is an abstract class. +You must choose one of the three provided subclasses, :class:`vtkm::rendering::View3D`, :class:`vtkm::rendering::View2D`, and :class:`vtkm::rendering::View3D`, depending on the type of data being presented. +All three view classes take a :class:`vtkm::rendering::Scene`, a :class:`vtkm::rendering::Mapper`, and a :class:`vtkm::rendering::Canvas` as arguments to their constructor. + +.. load-example:: ConstructView + :file: GuideExampleRendering.cxx + :caption: Constructing a :class:`vtkm::rendering::View`. + +.. doxygenclass:: vtkm::rendering::View + :members: + +.. doxygenclass:: vtkm::rendering::View1D + :members: + +.. doxygenclass:: vtkm::rendering::View2D + :members: + +.. doxygenclass:: vtkm::rendering::View3D + :members: + +.. index:: + double: color; background + double: color; foreground + +The :class:`vtkm::rendering::View` also maintains a background color (the color used in areas where nothing is drawn) and a foreground color (the color used for annotation elements). +By default, the :class:`vtkm::rendering::View` has a black background and a white foreground. +These can be set in the view's constructor, but it is a bit more readable to set them using the :func:`vtkm::rendering::View::SetBackground` and :func:`vtkm::rendering::View::SetForeground` methods. +In either case, the colors are specified using the :class:`vtkm::rendering::Color` helper class, which manages the red, green, and blue color channels as well as an optional alpha channel. +These channel values are given as floating point values between 0 and 1. + +.. load-example:: ViewColors + :file: GuideExampleRendering.cxx + :caption: Changing the background and foreground colors of a :class:`vtkm::rendering::View`. + +.. commonerrors:: + Although the background and foreground colors are set independently, it will be difficult or impossible to see the annotation if there is not enough contrast between the background and foreground colors. + Thus, when changing a :class:`vtkm::rendering::View`'s background color, it is always good practice to also change the foreground color. + +.. doxygenclass:: vtkm::rendering::Color + :members: + +Once the :class:`vtkm::rendering::View` is constructed, intialized, and set up, it is ready to render. +This is done by calling the :func:`vtkm::rendering::View::Paint` method. + +.. load-example:: PaintView + :file: GuideExampleRendering.cxx + :caption: Using :func:`vtkm::rendering::Canvas::Paint` in a display callback. + +Putting together :numref:`ex:ConstructView`, :numref:`ex:ViewColors`, and :numref:`ex:PaintView`, the final render of a view looks like that in :numref:`fig:ExampleRendering`. + +.. figure:: images/BasicRendering.png + :width: 100% + :name: fig:ExampleRendering + + Example output of |VTKm|'s rendering system. + +.. Note: BasicRendering.png is generated by the GuideExampleRendering.cxx code. + +Of course, the :class:`vtkm::rendering::CanvasRayTracer` created in :numref:`ex:ConstructView` is an offscreen rendering buffer, so you cannot immediately see the image. +When doing batch visualization, an easy way to output the image to a file for later viewing is with the :func:`vtkm::rendering::View::SaveAs` method. +This method can save the image in either PNG or in the portable pixelmap (PPM) format. + +.. load-example:: SaveView + :file: GuideExampleRendering.cxx + :caption: Saving the result of a render as an image file. + +We visit doing interactive rendering in a GUI later in :secref:`rendering:Interactive Rendering`. + + +------------------------------ +Changing Rendering Modes +------------------------------ + +:numref:`ex:ConstructView` constructs the default mapper for ray tracing, which renders the data as an opaque solid. +However, you can change the rendering mode by using one of the other mappers listed in :secref:`rendering:Mappers`. +For example, say you just wanted to see a wireframe representation of your data. +You can achieve this by using :class:`vtkm::rendering::MapperWireframer`. + +.. index:: + double: rendering; wireframe + +.. load-example:: MapperEdge + :file: GuideExampleRendering.cxx + :caption: Creating a mapper for a wireframe representation. + +Alternatively, perhaps you wish to render just the points of mesh. +:class:`vtkm::rendering::MapperGlyphScalar` renders the points as glyphs and also optionally can scale the glyphs based on field values. + +.. load-example:: MapperGlyphScalar + :file: GuideExampleRendering.cxx + :caption: Creating a mapper for point representation. + +These mappers respectively render the images shown in :numref:`fig:AlternateMappers`. +Other mappers, such as those that can render translucent volumes, are also available. + +.. figure:: images/AlternateRendering.png + :width: 100% + :name: fig:AlternateMappers + + Examples of alternate rendering modes using different mappers. + The top left image is rendered with :class:`vtkm::rendering::MapperWireframer`. + The top right and bottom left images are rendered with :class:`vtkm::rendering::MapperGlyphScalar`. + The bottom right image is rendered with :class:`vtkm::rendering::MapperGlyphVector`. + + +------------------------------ +Manipulating the Camera +------------------------------ + +.. index:: + double: rendering; camera + +The :class:`vtkm::rendering::View` uses an object called :class:`vtkm::rendering::Camera` to describe the vantage point from which to draw the geometry. +The camera can be retrieved from the :func:`vtkm::rendering::View::GetCamera` method. +That retrieved camera can be directly manipulated or a new camera can be provided by calling :func:`vtkm::rendering::View::SetCamera`. +In this section we discuss camera setups typical during view set up. +Camera movement during interactive rendering is revisited in :secref:`rendering:Camera Movement`. + +.. doxygenclass:: vtkm::rendering::Camera + :members: + +A :class:`vtkm::rendering::Camera` operates in one of two major modes: 2D mode or 3D mode. +2D mode is designed for looking at flat geometry (or close to flat geometry) that is parallel to the x-y plane. +3D mode provides the freedom to place the camera anywhere in 3D space. +The different modes can be set with :func:`vtkm::rendering::Camera::SetModeTo2D` and :func:`vtkm::rendering::Camera::SetModeTo3D`, respectively. +The interaction with the camera in these two modes is very different. + +Common Camera Controls +============================== + +Some camera controls operate relative to the rendered image and are common among the 2D and 3D camera modes. + +Pan +------------------------------ + +.. index:: + triple: camera; rendering; pan + +A camera pan moves the viewpoint left, right, up, or down. +A camera pan is performed by calling the :func:`vtkm::cont::Camera::Pan` method. +:func:`vtkm::cont::Camera::Pan` takes two arguments: the amount to pan in x and the amount to pan in y. + +The pan is given with respect to the projected space. So a pan of :math:`1` in +the x direction moves the camera to focus on the right edge of the image +whereas a pan of :math:`-1` in the x direction moves the camera to focus on the +left edge of the image. + +.. load-example:: Pan + :file: GuideExampleRenderingInteractive.cxx + :caption: Panning the camera. + +Zoom +------------------------------ + +.. index:: + triple: camera; rendering; zoom + +A camera zoom draws the geometry larger or smaller. +A camera zoom is performed by calling the :func:`vtkm::rendering::Camera::Zoom` method. +:func:`vtkm::rendering::Camera::Zoom` takes a single argument specifying the zoom factor. +A positive number draws the geometry larger (zoom in), and larger zoom factor results in larger geometry. +Likewise, a negative number draws the geometry smaller (zoom out). +A zoom factor of 0 has no effect. + +.. load-example:: Zoom + :file: GuideExampleRenderingInteractive.cxx + :caption: Zooming the camera. + +2D Camera Mode +============================== + +.. index:: + triple: camera; rendering; 2D + +The 2D camera is restricted to looking at some region of the x-y plane. + +View Range +------------------------------ + +.. index:: + triple: camera; rendering; view range + +The vantage point of a 2D camera can be specified by simply giving the region in the x-y plane to look at. +This region is specified by calling :func:`vtkm::rendering::Camera::SetViewRange2D`. +This method takes the left, right, bottom, and top of the region to view. +Typically these are set to the range of the geometry in world space as shown in :numref:`fig:CameraViewRange2D`. + +.. figure:: images/CameraViewRange2D.png + :width: 100% + :name: fig:CameraViewRange2D + + The view range bounds to give a :class:`vtkm::rendering::Camera`. + +3D Camera Mode +============================== + +.. index:: + triple: camera; rendering; 3D + double: pinhole; camera + +The 3D camera is a free-form camera that can be placed anywhere in 3D space and can look in any direction. +The projection of the 3D camera is based on the pinhole camera pinhole camera model in which all viewing rays intersect a single point. +This single point is the camera's position. + +Position and Orientation +------------------------------ + +.. index:: + triple: camera; rendering; position + triple: camera; rendering; look at + triple: camera; rendering; focal point + +The position of the camera, which is the point where the observer is viewing the scene, can be set with the :func:`vtkm::rendering::Camera::SetPosition` method. +The direction the camera is facing is specified by giving a position to focus on. +This is called either the "look at" point or the focal point and is specified with the :func:`vtkm::rendering::Camera::SetLookAt` method. +:numref:`fig:CameraPositionOrientation3D` shows the relationship between the position and look at points. + +.. figure:: images/CameraPositionOrientation.png + :width: 100% + :name: fig:CameraPositionOrientation3D + + The position and orientation parameters for a :class:`vtkm::rendering::Camera`. + +.. index:: + triple: camera; rendering; view up + triple: camera; rendering; up + +In addition to specifying the direction to point the camera, the camera must also know which direction is considered "up." +This is specified with the view up vector using the :func:`vtkm::rendering::Camera::SetViewUp` method. +The view up vector points from the camera position (in the center of the image) to the top of the image. +The view up vector in relation to the camera position and orientation is shown in :numref:`fig:CameraPositionOrientation3D`. + +.. index:: + triple: camera; rendering; field of view + +Another important parameter for the camera is its field of view. +The field of view specifies how wide of a region the camera can see. +It is specified by giving the angle in degrees of the cone of visible region emanating from the pinhole of the camera to the :func:`vtkm::rendering::Camera::SetFieldOfView` method. +The field of view angle in relation to the camera orientation is shown in :numref:`fig:CameraPositionOrientation3D`. +A field of view angle of :math:`60^{\circ}` usually works well. + +.. index:: + triple: camera; rendering; clipping range + triple: camera; rendering; near clip plane + triple: camera; rendering; far clip plane + +Finally, the camera must specify a clipping region that defines the valid range of depths for the object. +This is a pair of planes parallel to the image that all visible data must lie in. +Each of these planes is defined simply by their distance to the camera position. +The near clip plane is closer to the camera and must be in front of all geometry. +The far clip plane is further from the camera and must be behind all geometry. +The distance to both the near and far planes are specified with the :func:`vtkm::rendering::Camera::SetClippingRange` method. +:numref:`fig:CameraPositionOrientation3D` shows the clipping planes in relationship to the camera position and orientation. + +.. load-example:: CameraPositionOrientation + :file: GuideExampleRenderingInteractive.cxx + :caption: Directly setting :class:`vtkm::rendering::Camera` position and orientation. + +Movement +------------------------------ + +In addition to specifically setting the position and orientation of the camera, :class:`vtkm::rendering::Camera` contains several convenience methods that move the camera relative to its position and look at point. + +.. index:: + triple: camera; rendering; elevation + triple: camera; rendering; azimuth + +Two such methods are elevation and azimuth, which move the camera around the sphere centered at the look at point. +:func:`vtkm::rendering::Camera::Elevation` raises or lowers the camera. +Positive values raise the camera up (in the direction of the view up vector) whereas negative values lower the camera down. +:func:`vtkm::rendering::Camera::Azimuth` moves the camera around the look at point to the left or right. +Positive values move the camera to the right whereas negative values move the camera to the left. +Both :func:`vtkm::rendering::Camera::Elevation` and :func:`vtkm::rendering::Camera::Azimuth` specify the amount of rotation in terms of degrees. +:numref:`fig:CameraMovement` shows the relative movements of :func:`vtkm::rendering::Camera::Elevation` and :func:`vtkm::rendering::Camera::Azimuth`. + +.. figure:: images/CameraMovement.png + :width: 100% + :name: fig:CameraMovement + + :class:`vtkm::rendering::Camera` movement functions relative to position and orientation. + +.. load-example:: CameraMovement + :file: GuideExampleRenderingInteractive.cxx + :caption: Moving the camera around the look at point. + +.. commonerrors:: + The :func:`vtkm::rendering::Camera::Elevation` and :func:`vtkm::rendering::Camera::Azimuth` methods change the position of the camera, but not the view up vector. + This can cause some wild camera orientation changes when the direction of the camera view is near parallel to the view up vector, which often happens when the elevation is raised or lowered by about 90 degrees. + +In addition to rotating the camera around the look at point, you can move the camera closer or further from the look at point. +This is done with the :func:`vtkm::rendering::Camera::Dolly` method. +The :func:`vtkm::rendering::Camera::Dolly` method takes a single value that is the factor to scale the distance between camera and look at point. +Values greater than one move the camera away, values less than one move the camera closer. +The direction of dolly movement is shown in :numref:`fig:CameraMovement`. + +Finally, the :func:`vtkm::rendering::Camera::Roll` method rotates the camera around the viewing direction. +It has the effect of rotating the rendered image. +The :func:`vtkm::rendering::Camera::Roll` method takes a single value that is the angle to rotate in degrees. +The direction of roll movement is shown in :numref:`fig:CameraMovement`. + +Reset +------------------------------ + +.. index:: + triple: camera; rendering; reset + +Setting a specific camera position and orientation can be frustrating, particularly when the size, shape, and location of the geometry is not known a priori. +Typically this involves querying the data and finding a good camera orientation. + +To make this process simpler, the :func:`vtkm::rendering::Camera::ResetToBounds` convenience method automatically positions the camera based on the spatial bounds of the geometry. +The most expedient method to find the spatial bounds of the geometry being rendered is to get the :class:`vtkm::rendering::Scene` object and call :func:`vtkm::rendering::Scene::GetSpatialBounds`. +The :class:`vtkm::rendering::Scene` object can be retrieved from the :class:`vtkm::rendering::View`, which, as described in :secref:`rendering:Views`, is the central object for managing rendering. + +.. load-example:: ResetCamera + :file: GuideExampleRenderingInteractive.cxx + :caption: Resetting a :class:`vtkm::rendering::Camera` to view geometry. + +The :func:`vtkm::rendering::Camera::ResetToBounds` method operates by placing the look at point in the center of the bounds and then placing the position of the camera relative to that look at point. +The position is such that the view direction is the same as before the call to :func:`vtkm::rendering::Camera::ResetToBounds` and the distance between the camera position and look at point has the bounds roughly fill the rendered image. +This behavior is a convenient way to update the camera to make the geometry most visible while still preserving the viewing position. +If you want to reset the camera to a new viewing angle, it is best to set the camera to be pointing in the right direction and then calling :func:`vtkm::rendering::Camera::ResetToBounds` to adjust the position. + +.. load-example:: AxisAlignedCamera + :file: GuideExampleRenderingInteractive.cxx + :caption: Resetting a :class:`vtkm::rendering::Camera` to be axis aligned. + + +------------------------------ +Interactive Rendering +------------------------------ + +.. index:: + double: rendering; interactive + +So far in our description of |VTKm|'s rendering capabilities we have talked about doing rendering of fixed scenes. +However, an important use case of scientific visualization is to provide an interactive rendering system to explore data. +In this case, you want to render into a GUI application that lets the user interact manipulate the view. +The full design of a 3D visualization application is well outside the scope of this book, but we discuss in general terms what you need to plug |VTKm|'s rendering into such a system. + +In this section we discuss two important concepts regarding interactive rendering. +First, we need to write images into a GUI while they are being rendered. +Second, we want to translate user interaction to camera movement. + +Rendering Into a GUI +============================== + +.. index:: + triple: interactive; rendering; OpenGL + +Before being able to show rendering to a user, we need a system rendering context in which to push the images. +In this section we demonstrate the display of images using the OpenGL rendering system, which is common for scientific visualization applications. +That said, you could also use other rendering systems like DirectX or even paste images into a blank widget. + +Creating an OpenGL context varies depending on the OS platform you are using. +If you do not already have an application you want to integrate with |VTKm|'s rendering, you may wish to start with graphics utility API such as GLUT or GLFW. +The process of initializing an OpenGL context is not discussed here. + +The process of rendering into an OpenGL context is straightforward. +First call :func:`vtkm::rendering::View::Paint` on the :class:`vtkm::rendering::View` object to do the actual rendering. +Second, get the image color data out of the :class:`vtkm::rendering::View`'s :class:`vtkm::rendering::Canvas` object. +This is done by calling :func:`vtkm::rendering::Canvas::GetColorBuffer`. +This will return a :class:`vtkm::cont::ArrayHandle` object containing the image's pixel color data. +(:class:`vtkm::cont::ArrayHandle` is discussed in detail in Chapter \ref{chap:BasicArrayHandles} and subsequent chapters.) +A raw pointer can be pulled out of this :class:`vtkm::cont::ArrayHandle` by casting it to the :class:`vtkm::cont::ArrayHandleBase` subclass and calling the :func:`vtkm::cont::ArrayHandleBase::GetReadPointer` method on that. +Third, the pixel color data are pasted into the OpenGL render context. +There are multiple ways to do so, but the most straightforward way is to use the ``glDrawPixels`` function provided by OpenGL. +Fourth, swap the OpenGL buffers. +The method to swap OpenGL buffers varies by OS platform. +The aforementioned graphics libraries GLUT and GLFW each provide a function for doing so. + +.. todo:: Fix chapter reference above. + +.. load-example:: RenderToOpenGL + :file: GuideExampleRenderingInteractive.cxx + :caption: Rendering a :class:`vtkm::rendering::View` and pasting the result to an active OpenGL context. + +Camera Movement +============================== + +.. index:: + triple: interactive; rendering; camera + triple: camera; rendering; mouse + +When interactively manipulating the camera in a windowing system, the camera is usually moved in response to mouse movements. +Typically, mouse movements are detected through callbacks from the windowing system back to your application. +Once again, the details on how this works depend on your windowing system. +The assumption made in this section is that through the windowing system you will be able to track the x-y pixel location of the mouse cursor at the beginning of the movement and the end of the movement. +Using these two pixel coordinates, as well as the current width and height of the render space, we can make several typical camera movements. + +.. commonerrors:: + Pixel coordinates in |VTKm|'s rendering system originate in the lower-left corner of the image. + However, windowing systems generally report mouse coordinates with the origin in the *upper*-left corner. + The upshot is that the y coordinates will have to be reversed when translating mouse coordinates to |VTKm| image coordinates. + This inverting is present in all the following examples. + +Interactive Rotate +------------------------------ + +.. index:: + double: mouse; rotation + double: rotation; rendering + +A common and important mode of interaction with 3D views is to allow the user to rotate the object under inspection by dragging the mouse. +To facilitate this type of interactive rotation, :class:`vtkm::rendering::Camera` provides a convenience method named :func:`vtkm::rendering::Camera::TrackballRotate`. +It takes a start and end position of the mouse on the image and rotates viewpoint as if the user grabbed a point on a sphere centered in the image at the start position and moved under the end position. + +The :func:`vtkm::rendering::Camera::TrackballRotate` method is typically called from within a mouse movement callback. +The callback must record the pixel position from the last event and the new pixel position of the mouse. +Those pixel positions must be normalized to the range -1 to 1 where the position (-1,-1) refers to the lower left of the image and (1,1) refers to the upper right of the image. +The following example demonstrates the typical operations used to establish rotations when dragging the mouse. + +.. load-example:: MouseRotate + :file: GuideExampleRenderingInteractive.cxx + :caption: Interactive rotations through mouse dragging with :func:`vtkm::rendering::Camera::TrackballRotate`. + +Interactive Pan +------------------------------ + +.. index:: + double: mouse; pan + double: pan; rendering + +Panning can be performed by calling :func:`vtkm::rendering::Camera::Pan` with the translation relative to the width and height of the canvas. +For the translation to track the movement of the mouse cursor, simply scale the pixels the mouse has traveled by the width and height of the image. + +.. load-example:: MousePan + :file: GuideExampleRenderingInteractive.cxx + :caption: Pan the view based on mouse movements. + +Interactive Zoom +------------------------------ + +.. index:: + double: mouse; zoom + double: zoom; rendering + +Zooming can be performed by calling :func:`vtkm::rendering::Camera::Zoom` with a positive or negative zoom factor. +When using :func:`vtkm::rendering::Camera::Zoom` to respond to mouse movements, a natural zoom will divide the distance traveled by the mouse pointer by the width or height of the screen as demonstrated in the following example. + +.. load-example:: MouseZoom + :file: GuideExampleRenderingInteractive.cxx + :caption: Zoom the view based on mouse movements. + + +------------------------------ +Color Tables +------------------------------ + +.. index:: + double: rendering; color tables + +An important feature of |VTKm|'s rendering units is the ability to :index:`pseudocolor` objects based on scalar data. +This technique maps each scalar to a potentially unique color. +This mapping from scalars to colors is defined by a :class:`vtkm::cont::ColorTable` object. +A :class:`vtkm::cont::ColorTable` can be specified as an optional argument when constructing a :class:`vtkm::rendering::Actor`. +(Use of :class:`vtkm::rendering::Actor` is discussed in :secref:`rendering:Scenes and Actors`.) + +.. load-example:: SpecifyColorTable + :file: GuideExampleRenderingInteractive.cxx + :caption: Specifying a :class:`vtkm::cont::ColorTable` for a :class:`vtkm::rendering::Actor`. + +.. doxygenclass:: vtkm::cont::ColorTable + :members: + +The easiest way to create a :class:`vtkm::cont::ColorTable` is to provide the +name of one of the many predefined sets of color provided by VTK-m. A list +of all available predefined color tables is provided below. + +.. This file and all the images in images/color-tables are built by the GuideExampleColorTables test. +.. include:: color-table-presets.rst + +* |Viridis| ``Viridis`` + Matplotlib Virdis, which is designed to have perceptual uniformity, accessibility to color blind viewers, and good conversion to black and white. + This is the default color map. +* |Cool-to-Warm| ``Cool to Warm`` + A color table designed to be perceptually even, to work well on shaded 3D surfaces, and to generally perform well across many uses. +* |Cool-to-Warm-Extended| ``Cool to Warm Extended`` + This colormap is an expansion on cool to warm that moves through a wider range of hue and saturation. + Useful if you are looking for a greater level of detail, but the darker colors at the end might interfere with 3D surfaces. +* |Inferno| ``Inferno`` + Matplotlib Inferno, which is designed to have perceptual uniformity, accessibility to color blind viewers, and good conversion to black and white. +* |Plasma| ``Plasma`` + Matplotlib Plasma, which is designed to have perceptual uniformity, accessibility to color blind viewers, and good conversion to black and white. +* |Black-Body-Radiation| ``Black Body Radiation`` + The colors are inspired by the wavelengths of light from black body radiation. + The actual colors used are designed to be perceptually uniform. +* |X-Ray| ``X Ray`` + Greyscale colormap useful for making volume renderings similar to what you would expect in an x-ray. +* |Green| ``Green`` + A sequential color map of green varied by saturation. +* |Black---Blue---White| ``Black - Blue - White`` + A sequential color map from black to blue to white. +* |Blue-to-Orange| ``Blue to Orange`` + A double-ended (diverging) color table that goes from dark blues to a neutral white and then a dark orange at the other end. +* |Gray-to-Red| ``Gray to Red`` + A double-ended (diverging) color table with black/gray at the low end and orange/red at the high end. +* |Cold-and-Hot| ``Cold and Hot`` + A double-ended color map with a black middle color and diverging values to either side. + Colors go from red to yellow on the positive side and through blue on the negative side. +* |Blue---Green---Orange| ``Blue - Green - Orange`` + A three-part color map with blue at the low end, green in the middle, and orange at the high end. +* |Yellow---Gray---Blue| ``Yellow - Gray - Blue`` + A three-part color map with yellow at the low end, gray in the middle, and blue at the high end. +* |Rainbow-Uniform| ``Rainbow Uniform`` + A color table that spans the hues of a rainbow. + This color table modifies the hues to make them more perceptually uniform than the raw color wavelengths. +* |Jet| ``Jet`` + A rainbow color table that adds some darkness for greater perceptual resolution. +* |Rainbow-Desaturated| ``Rainbow Desaturated`` + Basic rainbow colors with periodic dark points to increase the local discriminability. diff --git a/docs/users-guide/running-filters.rst b/docs/users-guide/running-filters.rst new file mode 100644 index 000000000..4735d9004 --- /dev/null +++ b/docs/users-guide/running-filters.rst @@ -0,0 +1,188 @@ +============================== +Running Filters +============================== + +.. index:: filter + +Filters are functional units that take data as input and write new data as output. +Filters operate on :class:`vtkm::cont::DataSet` objects, which are described in :chapref:`dataset:Data Sets`. + +.. didyouknow:: + The structure of filters in |VTKm| is significantly simpler than their counterparts in VTK. + VTK filters are arranged in a dataflow network (a.k.a. a visualization pipeline) and execution management is handled automatically. + In contrast, |VTKm| filters are simple imperative units, which are simply called with input data and return output data. + +|VTKm| comes with several filters ready for use. +This chapter gives an overview of how to run the filters. +:chapref:`provided-filters:Provided Filters` describes the common filters provided by |VTKm|. +Later, :partref:`part-developing:Developing Algorithms` describes the necessary steps in creating new filters in |VTKm|. + + +------------------------------ +Basic Filter Operation +------------------------------ + +Different filters will be used in different ways, but the basic operation of all filters is to instantiate the filter class, set the state parameters on the filter object, and then call the filter's :func:`vtkm::filter::Filter::Execute` method. +It takes a :class:`vtkm::cont::DataSet` and returns a new :class:`vtkm::cont::DataSet`, which contains the modified data. +The :func:`vtkm::filter::Filter::Execute` method can alternately take a :class:`vtkm::cont::PartitionedDataSet` object, which is a composite of :class:`vtkm::cont::DataSet` objects. +In this case :func:`vtkm::filter::Filter::Execute` will return another :class:`vtkm::cont::PartitionedDataSet` object. + +The following example provides a simple demonstration of using a filter. +It specifically uses the point elevation filter to estimate the air pressure at each point based on its elevation. + +.. load-example:: PointElevation + :file: GuideExampleProvidedFilters.cxx + :caption: Using :class:`vtkm::filter::field_transform::PointElevation` to estiate air pressure. + +We see that this example follows the previously described procedure of constructing the filter (:exlineref:`line %s`), setting the state parameters (:exlineref:`lines %s` :exlineref:`-- %s`), and finally executing the filter on a :class:`vtkm::cont::DataSet` (:exlineref:`line %s`). + +.. index:: field + +Every :class:`vtkm::cont::DataSet` object contains a list of *fields*, which describe some numerical value associated with different parts of the data set in space. +Fields often represent physical properties such as temperature, pressure, or velocity. +Fields are identified with string names. +There are also special fields called coordinate systems that describe the location of points in space. +Field are mentioned here because they are often used as input data to the filter's operation and filters often generate new fields in the output. +This is the case in :numref:`ex:PointElevation`. +In :exlineref:`line %s` the coordinate system is set as the input field and in :exlineref:`line %s` the name to use for the generated output field is selected. + + +------------------------------ +Advanced Field Management +------------------------------ + +.. index:: + double: filter; fields + +Most filters work with fields as inputs and outputs to their algorithms. +Although in the previous discussions of the filters we have seen examples of specifying fields, these examples have been kept brief in the interest of clarity. +In this section we revisit how filters manage fields and provide more detailed documentation of the controls. + +Note that not all of the discussion in this section applies to all the filters provided by |VTKm|. +For example, not all filters have a specified input field. +But where possible, the interface to the filter objects is kept consistent. + +Input Fields +============================== + +.. index:: + triple: filter; input; fields + +Filters that take one or more fields as input have a common set of methods to set the "active" fields to operate on. +They might also have custom methods to ease setting the appropriate fields, but these are the base methods. + +.. doxygenfunction:: vtkm::filter::FilterField::SetActiveField(const std::string&, vtkm::cont::Field::Association) + +.. doxygenfunction:: vtkm::filter::FilterField::SetActiveField(vtkm::IdComponent, const std::string&, vtkm::cont::Field::Association) + +.. doxygenfunction:: vtkm::filter::FilterField::GetActiveFieldName + +.. doxygenfunction:: vtkm::filter::FilterField::GetActiveFieldAssociation + +.. doxygenfunction:: vtkm::filter::FilterField::SetActiveCoordinateSystem(vtkm::Id) + +.. doxygenfunction:: vtkm::filter::FilterField::SetActiveCoordinateSystem(vtkm::IdComponent, vtkm::Id) + +.. doxygenfunction:: vtkm::filter::FilterField::GetActiveCoordinateSystemIndex + +.. doxygenfunction:: vtkm::filter::FilterField::SetUseCoordinateSystemAsField(bool) + +.. doxygenfunction:: vtkm::filter::FilterField::SetUseCoordinateSystemAsField(vtkm::IdComponent, bool) + +.. doxygenfunction:: vtkm::filter::FilterField::GetUseCoordinateSystemAsField + +.. doxygenfunction:: vtkm::filter::FilterField::GetNumberOfActiveFields + +The :func:`vtkm::filter::FilterField::SetActiveField` takes an optional argument that specifies which topological elements the field is associated with (such as points or cells). +The :enum:`vtkm::cont::Field::Association` enumeration is used to select the field association. + +.. load-example:: SetActiveFieldWithAssociation + :file: GuideExampleProvidedFilters.cxx + :caption: Setting a field's active filter with an association. + +.. commonerrors:: + It is possible to have two fields with the same name that are only differentiable by the association. + That is, you could have a point field and a cell field with different data but the same name. + Thus, it is best practice to specify the field association when possible. + Likewise, it is poor practice to have two fields with the same name, particularly if the data are not equivalent in some way. + It is often the case that fields are selected without an association. + +It is also possible to set the active scalar field as a coordinate system of the data. +A coordinate system essentially provides the spatial location of the points of the data and they have a special place in the :class:`vtkm::cont::DataSet` structure. +(See :secref:`dataset:Coordinate Systems` for details on coordinate systems.) +You can use a coordinate system as the active scalars by calling the :func:`vtkm::filter::FilterField::SetUseCoordinateSystemAsField` method with a true flag. +Since a :class:`vtkm::cont::DataSet` can have multiple coordinate systems, you can select the desired coordinate system with :func:`vtkm::filter::FilterField::SetActiveCoordinateSystem`. +(By default, the first coordinate system, index 0, will be used.) + +.. load-example:: SetCoordinateSystem + :file: GuideExampleProvidedFilters.cxx + :caption: Setting the active coordinate system. + +Passing Fields from Input to Output +======================================== + +.. index:: + triple: filter; passing; fields + +After a filter successfully executes and returns a new data set, fields are mapped from input to output. +Depending on what operation the filter does, this could be a simple shallow copy of an array, or it could be a computed operation. +By default, the filter will automatically pass all fields from input to output (performing whatever transformations are necessary). +You can control which fields are passed (and equivalently which are not) with the :func:`vtkm::filter::Filter::SetFieldsToPass` methods. + +.. doxygenfunction:: vtkm::filter::Filter::SetFieldsToPass(vtkm::filter::FieldSelection&&) + +There are multiple ways to to use :func:`vtkm::filter::Filter::SetFieldsToPass` to control what fields are passed. +If you want to turn off all fields so that none are passed, call :func:`vtkm::filter::Filter::SetFieldsToPass` with :enum:`vtkm::filter::FieldSelection::Mode::None`. + +.. load-example:: PassNoFields + :file: GuideExampleProvidedFilters.cxx + :caption: Turning off the passing of all fields when executing a filter. + +If you want to pass one specific field, you can pass that field's name to :func:`vtkm::filter::Filter::SetFieldsToPass`. + +.. load-example:: PassOneField + :file: GuideExampleProvidedFilters.cxx + :caption: Setting one field to pass by name. + +Or you can provide a list of fields to pass by giving :func:`vtkm::filter::Filter::SetFieldsToPass` an initializer list of names. + +.. load-example:: PassListOfFields + :file: GuideExampleProvidedFilters.cxx + :caption: Using a list of fields for a filter to pass. + +If you want to instead select a list of fields to *not* pass, you can add :enum:`vtkm::filter::FieldSelection::Mode::Exclude` as an argument to :func:`vtkm::filter::Filter::SetFieldsToPass`. + +.. load-example:: PassExcludeFields + :file: GuideExampleProvidedFilters.cxx + :caption: Excluding a list of fields for a filter to pass. + +Ultimately, :func:`vtkm::filter::Filter::SetFieldsToPass` takes a :class:`vtkm::filter::FieldSelection` object. +You can create one directly to select (or exclude) specific fields and their associations. + +.. load-example:: FieldSelection + :file: GuideExampleProvidedFilters.cxx + :caption: Using :class:`vtkm::filter::FieldSelection` to select cells to pass. + +It is also possible to specify field attributions directly to :func:`vtkm::filter::Filter::SetFieldsToPass`. +If you only have one field, you can just specify both the name and attribution. +If you have multiple fields, you can provide an initializer list of ``std::pair`` or :class:`vtkm::Pair` containing a ``std::string`` and a :enum:`vtkm::cont::Field::Association`. +In either case, you can add an optional last argument of :enum:`vtkm::filter::FieldSelection::Mode::Exclude` to exclude the specified filters instead of selecting them. + +.. load-example:: PassFieldAndAssociation + :file: GuideExampleProvidedFilters.cxx + :caption: Selecting one field and its association for a filter to pass. + +.. load-example:: PassListOfFieldsAndAssociations + :file: GuideExampleProvidedFilters.cxx + :caption: Selecting a list of fields and their associations for a filter to pass. + +Note that coordinate systems in a :class:`vtkm::cont::DataSet` are simply links to point fields, and by default filters will pass coordinate systems regardless of the field selection flags. +To prevent a filter from passing a coordinate system if its associated field is not selected, use the :func:`vtkm::filter::Filter::SetPassCoordinateSystems` method. + +.. doxygenfunction:: vtkm::filter::Filter::SetPassCoordinateSystems + +.. doxygenfunction:: vtkm::filter::Filter::GetPassCoordinateSystems + +.. load-example:: PassNoCoordinates + :file: GuideExampleProvidedFilters.cxx + :caption: Turning off the automatic selection of fields associated with a :class:`vtkm::cont::DataSet`'s coordinate system. diff --git a/docs/users-guide/timer.rst b/docs/users-guide/timer.rst new file mode 100644 index 000000000..4f8d014cb --- /dev/null +++ b/docs/users-guide/timer.rst @@ -0,0 +1,42 @@ +============================== +Timers +============================== + +.. index:: timer + +It is often the case that you need to measure the time it takes for an operation to happen. +This could be for performing measurements for algorithm study or it could be to dynamically adjust scheduling. + +Performing timing in a multi-threaded environment can be tricky because operations happen asynchronously. +To ensure that accurate timings can be made, |VTKm| provides a :class:`vtkm::cont::Timer` class to provide an accurate measurement of operations that happen on devices that |VTKm| can use. +By default, :class:`vtkm::cont::Timer` will time operations on all possible devices. + +The timer is started by calling the :func:`vtkm::cont::Timer::Start` method. +The timer can subsequently be stopped by calling :func:`vtkm::cont::Timer::Stop`. +The time elapsed between calls to :func:`vtkm::cont::Timer::Start` and :func:`vtkm::cont::Timer::Stop` (or the current time if :func:`vtkm::cont::Timer::Stop` was not called) can be retrieved with a call to the :func:`vtkm::cont::Timer::GetElapsedTime` method. +Subsequently calling :func:`vtkm::cont::Timer::Start` again will restart the timer. + +.. load-example:: Timer + :file: GuideExampleTimer.cxx + :caption: Using :class:`vtkm::cont::Timer`. + +.. commonerrors:: + Some device require data to be copied between the host CPU and the device. + In this case you might want to measure the time to copy data back to the host. + This can be done by "touching" the data on the host by getting a control portal. + +The |VTKm| :class:`vtkm::cont::Timer` does its best to capture the time it takes for all parallel operations run between calls to :func:`vtkm::cont::Timer::Start` and :func:`vtkm::cont::Timer::Stop` to complete. +It does so by synchronizing to concurrent execution on devices that might be in use. + +.. commonerrors:: + Because :class:`vtkm::cont::Timer` synchronizes with devices (essentially waiting for the device to finish executing), that can have an effect on how your program runs. + Be aware that using a :class:`vtkm::cont::Timer` can itself change the performance of your code. + In particular, starting and stopping the timer many times to measure the parts of a sequence of operations can potentially make the whole operation run slower. + +By default, :class:`vtkm::cont::Timer` will synchronize with all active devices. +However, if you want to measure the time for a specific device, then you can pass the device adapter tag or id to :class:`vtkm::cont::Timer`'s constructor. +You can also change the device being used by passing a device adapter tag or id to the :func:`vtkm::cont::Timer::Reset` method. +A device can also be specified through an optional argument to the :func:`vtkm::cont::Timer::GetElapsedTime` method. + +.. doxygenclass:: vtkm::cont::Timer + :members: diff --git a/docs/users-guide/version.rst b/docs/users-guide/version.rst new file mode 100644 index 000000000..33215fcf4 --- /dev/null +++ b/docs/users-guide/version.rst @@ -0,0 +1,67 @@ +============================== +VTK-m Version +============================== + +.. index:: version + +As the |VTKm| code evolves, changes to the interface and behavior will +inevitably happen. +Consequently, code that links into |VTKm| might need a specific version of +|VTKm| or changes its behavior based on what version of |VTKm| it is using. +To facilitate this, |VTKm| software is managed with a versioning system and +advertises its version in multiple ways. +As with many software products, |VTKm| has three version numbers: major, +minor, and patch. +The major version represents significant changes in the |VTKm| +implementation and interface. +Changes in the major version include backward incompatible changes. +The minor version represents added functionality. +Generally, changes in the minor version to not introduce changes to the API. +The patch version represents fixes provided after a release occurs. +Patch versions represent minimal change and do not add features. + +.. index:: + triple: CMake ; VTK-m package ; version + +If you are writing a software package that is managed by CMake and load |VTKm| with the :cmake:command:`find_package` command as described in :secref:`building:Linking to |VTKm|`, then you can query the |VTKm| version directly in the CMake configuration. +When you load |VTKm| with :cmake:command:`find_package`, CMake sets the variables :cmake:variable:`VTKm_VERSION_MAJOR`, :cmake:variable:`VTKm_VERSION_MINOR`, and :cmake:variable:`VTKm_VERSION_PATCH` to the major, minor, and patch versions, respectively. +Additionally, :cmake:variable:`VTKm_VERSION` is set to the "major.minor" version number and :cmake:variable:`VTKm_VERSION_FULL` is set to the "major.minor.patch" version number. +If the current version of |VTKm| is actually a development version that is in between releases of |VTKm|, then and abbreviated SHA of the git commit is also included as part of :cmake:variable:`VTKm_VERSION_FULL`. + +.. didyouknow:: + If you have a specific version of |VTKm| required for your software, you can also use the version option to the :cmake:command:`find_package` CMake command. + The :cmake:command:`find_package` command takes an optional version argument that causes the command to fail if the wrong version of the package is found. + +.. index:: version ; macro + +It is also possible to query the |VTKm| version directly in your code through preprocessor macros. +The :file:`vtkm/Version.h` header file defines the following preprocessor macros to identify the |VTKm| version. + +.. c:macro:: VTKM_VERSION + + The version number of the loaded |VTKm| package. + This is in the form "major.minor". + +.. c:macro:: VTKM_VERSION_FULL + + The extended version number of the |VTKm| package including patch and in-between-release information. + This is in the form "major.minor.patch[.gitsha1]" where "gitsha" is only included if the source code is in between releases. + +.. c:macro:: VTKM_VERSION_MAJOR + + The major |VTKm| version number. + +.. c:macro:: VTKM_VERSION_MINOR + + The minor |VTKm| version number. + +.. c:macro:: VTKM_VERSION_PATCH + + The patch |VTKm| version number. + +.. commonerrors:: + Note that the CMake variables all begin with ``VTKm_`` (lowercase "m") whereas the preprocessor macros begin with ``VTKM_`` (all uppercase). + This follows the respective conventions of CMake variables and preprocessor macros. + +Note that :file:`vtkm/Version.h` does not include any other |VTKm| header files. +This gives your code a chance to load, query, and react to the |VTKm| version before loading any |VTKm| code proper. diff --git a/docs/users-guide/vtkm.module b/docs/users-guide/vtkm.module index 43a7cb7f0..79c32cb39 100644 --- a/docs/users-guide/vtkm.module +++ b/docs/users-guide/vtkm.module @@ -6,5 +6,10 @@ TESTING_DIR examples TEST_DEPENDS vtkm_cont + vtkm_filter_contour + vtkm_filter_field_conversion + vtkm_filter_field_transform + vtkm_filter_flow + vtkm_filter_geometry_refinement vtkm_filter_mesh_info vtkm_rendering diff --git a/vtkm/ImplicitFunction.h b/vtkm/ImplicitFunction.h index e5544a6d8..eab047f72 100644 --- a/vtkm/ImplicitFunction.h +++ b/vtkm/ImplicitFunction.h @@ -42,11 +42,27 @@ public: using Scalar = vtkm::FloatDefault; using Vector = vtkm::Vec; + /// @brief Evaluate the value of the implicit function. + /// + /// The `Value()` method for an implicit function takes a `vtkm::Vec3f` and + /// returns a `vtkm::FloatDefault` representing the orientation of the point + /// with respect to the implicit function's shape. Negative scalar values + /// represent vector points inside of the implicit function's shape. Positive + /// scalar values represent vector points outside the implicit function's shape. + /// Zero values represent vector points that lie on the surface of the implicit + /// function. VTKM_EXEC_CONT Scalar Value(Scalar x, Scalar y, Scalar z) const { return reinterpret_cast(this)->Value(Vector(x, y, z)); } + /// @brief Evaluate the gradient of the implicit function. + /// + /// The ``Gradient()`` method for an implicit function takes a `vtkm::Vec3f` + /// and returns a `vtkm::Vec3f` representing the pointing direction from the + /// implicit function's shape. Gradient calculations are more object shape + /// specific. It is advised to look at the individual shape implementations + /// for specific implicit functions. VTKM_EXEC_CONT Vector Gradient(Scalar x, Scalar y, Scalar z) const { return reinterpret_cast(this)->Gradient(Vector(x, y, z)); @@ -130,9 +146,9 @@ private: }; //============================================================================ -/// \brief Implicit function for a box +/// @brief Implicit function for a box /// -/// \c Box computes the implicit function and/or gradient for a axis-aligned +/// `Box` computes the implicit function and/or gradient for a axis-aligned /// bounding box. Each side of the box is orthogonal to all other sides /// meeting along shared edges and all faces are orthogonal to the x-y-z /// coordinate axes. @@ -140,41 +156,50 @@ private: class VTKM_ALWAYS_EXPORT Box : public internal::ImplicitFunctionBase { public: - /// \brief Construct box with center at (0,0,0) and each side of length 1.0. + /// @brief Construct box with center at (0,0,0) and each side of length 1.0. VTKM_EXEC_CONT Box() : MinPoint(Vector(Scalar(-0.5))) , MaxPoint(Vector(Scalar(0.5))) { } + /// @brief Construct a box with the specified minimum and maximum point. VTKM_EXEC_CONT Box(const Vector& minPoint, const Vector& maxPoint) : MinPoint(minPoint) , MaxPoint(maxPoint) { } + /// @brief Construct a box with the specified minimum and maximum point. VTKM_EXEC_CONT Box(Scalar xmin, Scalar xmax, Scalar ymin, Scalar ymax, Scalar zmin, Scalar zmax) : MinPoint(xmin, ymin, zmin) , MaxPoint(xmax, ymax, zmax) { } + /// @brief Construct a box that encompasses the given bounds. VTKM_CONT Box(const vtkm::Bounds& bounds) { this->SetBounds(bounds); } + /// @brief Specify the minimum coordinate of the box. VTKM_CONT void SetMinPoint(const Vector& point) { this->MinPoint = point; } + /// @brief Specify the maximum coordinate of the box. VTKM_CONT void SetMaxPoint(const Vector& point) { this->MaxPoint = point; } + /// @copydoc SetMinPoint VTKM_EXEC_CONT const Vector& GetMinPoint() const { return this->MinPoint; } + /// @copydoc SetMaxPoint VTKM_EXEC_CONT const Vector& GetMaxPoint() const { return this->MaxPoint; } + /// @brief Specify the size and location of the box by the bounds it encompasses. VTKM_CONT void SetBounds(const vtkm::Bounds& bounds) { this->SetMinPoint({ Scalar(bounds.X.Min), Scalar(bounds.Y.Min), Scalar(bounds.Z.Min) }); this->SetMaxPoint({ Scalar(bounds.X.Max), Scalar(bounds.Y.Max), Scalar(bounds.Z.Max) }); } + /// @copydoc SetBounds VTKM_EXEC_CONT vtkm::Bounds GetBounds() const { return vtkm::Bounds(vtkm::Range(this->MinPoint[0], this->MaxPoint[0]), @@ -182,6 +207,7 @@ public: vtkm::Range(this->MinPoint[2], this->MaxPoint[2])); } + /// @copydoc internal::ImplicitFunctionBase::Value VTKM_EXEC_CONT Scalar Value(const Vector& point) const { Scalar minDistance = vtkm::NegativeInfinity32(); @@ -250,6 +276,7 @@ public: } } + /// @copydoc internal::ImplicitFunctionBase::Gradient VTKM_EXEC_CONT Vector Gradient(const Vector& point) const { vtkm::IdComponent minAxis = 0; @@ -400,6 +427,8 @@ public: { } + /// Construct a cylinder with the given axis and radius. + /// The cylinder is centered at the origin. VTKM_EXEC_CONT Cylinder(const Vector& axis, Scalar radius) : Center(Scalar(0)) , Axis(axis) @@ -407,6 +436,7 @@ public: { } + /// Construct a cylinder at the given center, axis, and radius. VTKM_EXEC_CONT Cylinder(const Vector& center, const Vector& axis, Scalar radius) : Center(center) , Axis(vtkm::Normal(axis)) @@ -414,12 +444,18 @@ public: { } + /// @brief Specify the center of the cylinder. + /// + /// The axis of the cylinder goes through the center. VTKM_CONT void SetCenter(const Vector& center) { this->Center = center; } + /// @brief Specify the direction of the axis of the cylinder. VTKM_CONT void SetAxis(const Vector& axis) { this->Axis = vtkm::Normal(axis); } + /// @brief Specify the radius of the cylinder. VTKM_CONT void SetRadius(Scalar radius) { this->Radius = radius; } + /// @copydoc internal::ImplicitFunctionBase::Value VTKM_EXEC_CONT Scalar Value(const Vector& point) const { Vector x2c = point - this->Center; @@ -427,6 +463,7 @@ public: return vtkm::Dot(x2c, x2c) - (proj * proj) - (this->Radius * this->Radius); } + /// @copydoc internal::ImplicitFunctionBase::Gradient VTKM_EXEC_CONT Vector Gradient(const Vector& point) const { Vector x2c = point - this->Center; @@ -442,20 +479,25 @@ private: }; //============================================================================ -/// \brief Implicit function for a frustum +/// @brief Implicit function for a frustum class VTKM_ALWAYS_EXPORT Frustum : public vtkm::internal::ImplicitFunctionBase { public: - /// \brief Construct axis-aligned frustum with center at (0,0,0) and each side of length 1.0. + /// @brief Construct axis-aligned frustum with center at (0,0,0) and each side of length 1.0. Frustum() = default; + /// @brief Construct a frustum defined with 6 planes of the given points and normals. VTKM_EXEC_CONT Frustum(const Vector points[6], const Vector normals[6]) { this->SetPlanes(points, normals); } + /// @brief Construct a frustum defined by the 8 points of the bounding hexahedron. + /// + /// The points should be specified in the order of hex-cell vertices VTKM_EXEC_CONT explicit Frustum(const Vector points[8]) { this->CreateFromPoints(points); } + /// @brief Specifies the 6 planes of the frustum. VTKM_EXEC void SetPlanes(const Vector points[6], const Vector normals[6]) { for (vtkm::Id index : { 0, 1, 2, 3, 4, 5 }) @@ -468,6 +510,7 @@ public: } } + /// @brief Set one of the 6 planes of the frustum. VTKM_EXEC void SetPlane(int idx, const Vector& point, const Vector& normal) { VTKM_ASSERT((idx >= 0) && (idx < 6)); @@ -475,6 +518,7 @@ public: this->Normals[idx] = normal; } + /// @copydoc SetPlanes VTKM_EXEC_CONT void GetPlanes(Vector points[6], Vector normals[6]) const { for (vtkm::Id index : { 0, 1, 2, 3, 4, 5 }) @@ -491,7 +535,9 @@ public: VTKM_EXEC_CONT const Vector* GetNormals() const { return this->Normals; } - // The points should be specified in the order of hex-cell vertices + /// @brief Specifies the frustum as the 8 points of the bounding hexahedron. + /// + /// The points should be specified in the order of hex-cell vertices VTKM_EXEC_CONT void CreateFromPoints(const Vector points[8]) { // XXX(clang-format-3.9): 3.8 is silly. 3.9 makes it look like this. @@ -512,6 +558,7 @@ public: } } + /// @copydoc internal::ImplicitFunctionBase::Value VTKM_EXEC_CONT Scalar Value(const Vector& point) const { Scalar maxVal = vtkm::NegativeInfinity(); @@ -525,6 +572,7 @@ public: return maxVal; } + /// @copydoc internal::ImplicitFunctionBase::Gradient VTKM_EXEC_CONT Vector Gradient(const Vector& point) const { Scalar maxVal = vtkm::NegativeInfinity(); @@ -581,18 +629,31 @@ public: { } + /// @brief Specify the origin of the plane. + /// + /// The origin can be any point on the plane. VTKM_CONT void SetOrigin(const Vector& origin) { this->Origin = origin; } + /// @brief Specify the normal vector to the plane. + /// + /// The magnitude of the plane does not matter (so long as it is more than zero) in terms + /// of the location of the plane where the implicit function equals 0. However, if offsets + /// away from the plane matter then the magnitude determines the scale of the value away + /// from the plane. VTKM_CONT void SetNormal(const Vector& normal) { this->Normal = normal; } + /// @copydoc SetOrigin VTKM_EXEC_CONT const Vector& GetOrigin() const { return this->Origin; } + /// @copydoc SetNormal VTKM_EXEC_CONT const Vector& GetNormal() const { return this->Normal; } + /// @copydoc internal::ImplicitFunctionBase::Value VTKM_EXEC_CONT Scalar Value(const Vector& point) const { return vtkm::Dot(point - this->Origin, this->Normal); } + /// @copydoc internal::ImplicitFunctionBase::Gradient VTKM_EXEC_CONT Vector Gradient(const Vector&) const { return this->Normal; } private: @@ -625,25 +686,32 @@ public: { } + /// Construct a sphere with the given center and radius. VTKM_EXEC_CONT Sphere(Vector center, Scalar radius) : Radius(radius) , Center(center) { } + /// Specify the radius of the sphere. VTKM_CONT void SetRadius(Scalar radius) { this->Radius = radius; } + /// Specify the center of the sphere. VTKM_CONT void SetCenter(const Vector& center) { this->Center = center; } + /// @copydoc SetRadius VTKM_EXEC_CONT Scalar GetRadius() const { return this->Radius; } + /// @copydoc SetCenter VTKM_EXEC_CONT const Vector& GetCenter() const { return this->Center; } + /// @copydoc internal::ImplicitFunctionBase::Value VTKM_EXEC_CONT Scalar Value(const Vector& point) const { return vtkm::MagnitudeSquared(point - this->Center) - (this->Radius * this->Radius); } + /// @copydoc internal::ImplicitFunctionBase::Gradient VTKM_EXEC_CONT Vector Gradient(const Vector& point) const { return Scalar(2) * (point - this->Center); @@ -689,6 +757,8 @@ public: return this->Planes[idx]; } VTKM_CONT vtkm::VecVariable GetPlanes() const { return this->Planes; } + + /// @copydoc internal::ImplicitFunctionBase::Value VTKM_EXEC_CONT Scalar Value(const Vector& point) const { Scalar maxVal = vtkm::NegativeInfinity(); @@ -702,6 +772,8 @@ public: } return maxVal; } + + /// @copydoc internal::ImplicitFunctionBase::Gradient VTKM_EXEC_CONT Vector Gradient(const Vector& point) const { Scalar maxVal = vtkm::NegativeInfinity(); @@ -792,11 +864,13 @@ public: { } + /// @copydoc internal::ImplicitFunctionBase::Value VTKM_EXEC_CONT Scalar Value(const Vector& point) const { return this->Variant.CastAndCall(detail::ImplicitFunctionValueFunctor{}, point); } + /// @copydoc internal::ImplicitFunctionBase::Gradient VTKM_EXEC_CONT Vector Gradient(const Vector& point) const { return this->Variant.CastAndCall(detail::ImplicitFunctionGradientFunctor{}, point); @@ -804,7 +878,7 @@ public: }; //============================================================================ -/// \brief Implicit function that can switch among known implicit function types. +/// @brief Implicit function that can switch among known implicit function types. /// /// `ImplicitFunctionGeneral` can behave as any of the predefined implicit functions /// provided by VTK-m. This is helpful when the type of implicit function is not @@ -817,6 +891,9 @@ public: /// function that you want to use, and then set the `ImplicitFunctionGeneral` /// to that concrete implicit function object. /// +/// `ImplicitFunctionGeneral` currently supports `vtkm::Box`, `vtkm::Cylinder`, +/// `vtkm::Frustum`, `vtkm::Plane`, and `vtkm::Sphere`. +/// class ImplicitFunctionGeneral : public vtkm::ImplicitFunctionMultiplexer Portals; vtkm::Id Index; + /// @cond NOPE friend vtkm::internal::ArrayPortalRecombineVec; + /// @endcond public: using ComponentType = typename std::remove_const::type; diff --git a/vtkm/cont/ArrayRangeComputeTemplate.h b/vtkm/cont/ArrayRangeComputeTemplate.h index 93e3fa287..54ade3d3e 100644 --- a/vtkm/cont/ArrayRangeComputeTemplate.h +++ b/vtkm/cont/ArrayRangeComputeTemplate.h @@ -490,6 +490,7 @@ struct StorageTagStride; } // vtkm::cont //------------------------------------------------------------------------------------------------- +/// @cond NOPE VTKM_INSTANTIATION_BEGIN VTK_M_ARRAY_RANGE_COMPUTE_ALL_SCALARS(extern template VTKM_CONT_TEMPLATE_EXPORT, vtkm::cont::StorageTagBasic); @@ -624,5 +625,6 @@ VTKM_INSTANTIATION_BEGIN VTK_M_ARRAY_RANGE_COMPUTE_ALL_SCALARS(extern template VTKM_CONT_TEMPLATE_EXPORT, vtkm::cont::StorageTagStride); VTKM_INSTANTIATION_END +/// @endcond #endif //vtk_m_cont_ArrayRangeComputeTemplate_h diff --git a/vtkm/cont/CellSet.h b/vtkm/cont/CellSet.h index 412591721..dfb666164 100644 --- a/vtkm/cont/CellSet.h +++ b/vtkm/cont/CellSet.h @@ -21,6 +21,10 @@ namespace vtkm namespace cont { +/// @brief Defines the topological structure of the data in a `DataSet`. +/// +/// Fundamentally, any cell set is a collection of cells, which typically (but not always) +/// represent some region in space. class VTKM_CONT_EXPORT CellSet { public: @@ -33,23 +37,37 @@ public: virtual ~CellSet(); + /// @brief Get the number of cells in the topology. virtual vtkm::Id GetNumberOfCells() const = 0; virtual vtkm::Id GetNumberOfFaces() const = 0; virtual vtkm::Id GetNumberOfEdges() const = 0; + /// @brief Get the number of points in the topology. virtual vtkm::Id GetNumberOfPoints() const = 0; + /// @brief Get the shell shape of a particular cell. virtual vtkm::UInt8 GetCellShape(vtkm::Id id) const = 0; + /// @brief Get the number of points incident to a particular cell. virtual vtkm::IdComponent GetNumberOfPointsInCell(vtkm::Id id) const = 0; + /// @brief Get a list of points incident to a particular cell. virtual void GetCellPointIds(vtkm::Id id, vtkm::Id* ptids) const = 0; + /// @brief Return a new `CellSet` that is the same derived class. virtual std::shared_ptr NewInstance() const = 0; + /// @brief Copy the provided `CellSet` into this object. + /// + /// The provided `CellSet` must be the same type as this one. virtual void DeepCopy(const CellSet* src) = 0; + /// @brief Print a summary of this cell set. virtual void PrintSummary(std::ostream&) const = 0; + /// @brief Remove the `CellSet` from any devices. + /// + /// Any memory used on a device to store this object will be deleted. + /// However, the data will still remain on the host. virtual void ReleaseResourcesExecution() = 0; }; diff --git a/vtkm/cont/CellSetExplicit.h b/vtkm/cont/CellSetExplicit.h index 69fb5db06..fc5789896 100644 --- a/vtkm/cont/CellSetExplicit.h +++ b/vtkm/cont/CellSetExplicit.h @@ -66,6 +66,10 @@ VTKM_CONT_EXPORT void BuildReverseConnectivity( #define VTKM_DEFAULT_OFFSETS_STORAGE_TAG VTKM_DEFAULT_STORAGE_TAG #endif +/// @brief Defines an irregular collection of cells. +/// +/// The cells can be of different types and connected in arbitrary ways. +/// This is done by explicitly providing for each cell a sequence of points that defines the cell. template @@ -146,17 +150,25 @@ public: VTKM_CONT void GetIndices(vtkm::Id index, vtkm::cont::ArrayHandle& ids) const; - /// First method to add cells -- one at a time. + /// @brief Start adding cells one at a time. + /// + /// After this method is called, `AddCell` is called repeatedly to add each cell. + /// Once all cells are added, call `CompleteAddingCells`. VTKM_CONT void PrepareToAddCells(vtkm::Id numCells, vtkm::Id connectivityMaxLen); + /// @brief Add a cell. + /// + /// This can only be called after `AddCell`. template VTKM_CONT void AddCell(vtkm::UInt8 cellType, vtkm::IdComponent numVertices, const IdVecType& ids); + /// @brief Finish adding cells one at a time. VTKM_CONT void CompleteAddingCells(vtkm::Id numPoints); - /// Second method to add cells -- all at once. - /// Assigns the array handles to the explicit connectivity. This is - /// the way you can fill the memory from another system without copying + /// @brief Set all the cells of the mesh. + /// + /// This method can be used to fill the memory from another system without + /// copying data. VTKM_CONT void Fill(vtkm::Id numPoints, const vtkm::cont::ArrayHandle& cellTypes, diff --git a/vtkm/cont/CellSetExtrude.h b/vtkm/cont/CellSetExtrude.h index be8285779..918e28aa0 100644 --- a/vtkm/cont/CellSetExtrude.h +++ b/vtkm/cont/CellSetExtrude.h @@ -46,6 +46,13 @@ struct CellSetExtrudeConnectivityChooser> @@ -324,17 +334,21 @@ public: using OriginalCellSetType = OriginalCellSetType_; using PermutationArrayHandleType = PermutationArrayHandleType_; - VTKM_CONT - CellSetPermutation(const PermutationArrayHandleType& validCellIds, - const OriginalCellSetType& cellset) + /// @brief Create a `CellSetPermutation`. + /// + /// @param[in] validCellIds An array that defines the permutation. If index @a i + /// is value @a j, then the @a ith cell of this cell set will be the same as + /// the @a jth cell in the original @a cellset. + /// @param[in] cellset The original cell set that this one is permuting. + VTKM_CONT CellSetPermutation(const PermutationArrayHandleType& validCellIds, + const OriginalCellSetType& cellset) : CellSet() , ValidCellIds(validCellIds) , FullCellSet(cellset) { } - VTKM_CONT - CellSetPermutation() + VTKM_CONT CellSetPermutation() : CellSet() , ValidCellIds() , FullCellSet() @@ -358,9 +372,11 @@ public: return *this; } + /// @brief Returns the original `CellSet` that this one is permuting. VTKM_CONT const OriginalCellSetType& GetFullCellSet() const { return this->FullCellSet; } + /// @brief Returns the array used to permute the cell indices. VTKM_CONT const PermutationArrayHandleType& GetValidCellIds() const { return this->ValidCellIds; } @@ -426,7 +442,12 @@ public: vtkm::cont::ArrayCopy(other->GetValidCellIds(), this->ValidCellIds); } - //This is the way you can fill the memory from another system without copying + /// @brief Set the topology. + /// + /// @param[in] validCellIds An array that defines the permutation. If index @a i + /// is value @a j, then the @a ith cell of this cell set will be the same as + /// the @a jth cell in the original @a cellset. + /// @param[in] cellset The original cell set that this one is permuting. VTKM_CONT void Fill(const PermutationArrayHandleType& validCellIds, const OriginalCellSetType& cellset) { diff --git a/vtkm/cont/CellSetSingleType.h b/vtkm/cont/CellSetSingleType.h index 3e4070429..47cb9bc4f 100644 --- a/vtkm/cont/CellSetSingleType.h +++ b/vtkm/cont/CellSetSingleType.h @@ -25,8 +25,17 @@ namespace vtkm namespace cont { -//Only works with fixed sized cell sets - +/// @brief An explicit cell set with all cells of the same shape. +/// +/// `CellSetSingleType` is an explicit cell set constrained to contain cells that +/// all have the same shape and all have the same number of points. So, for example +/// if you are creating a surface that you know will contain only triangles, +/// `CellSetSingleType` is a good representation for these data. +/// +/// Using `CellSetSingleType` saves memory because the array of cell shapes and the +/// array of point counts no longer need to be stored. `CellSetSingleType` also allows +/// VTK-m to skip some processing and other storage required for general explicit cell +/// sets. template class VTKM_ALWAYS_EXPORT CellSetSingleType : public vtkm::cont::CellSetExplicit< @@ -90,9 +99,11 @@ public: virtual ~CellSetSingleType() override {} - /// First method to add cells -- one at a time. - VTKM_CONT - void PrepareToAddCells(vtkm::Id numCells, vtkm::Id connectivityMaxLen) + /// @brief Start adding cells one at a time. + /// + /// After this method is called, `AddCell` is called repeatedly to add each cell. + /// Once all cells are added, call `CompleteAddingCells`. + VTKM_CONT void PrepareToAddCells(vtkm::Id numCells, vtkm::Id connectivityMaxLen) { this->CellShapeAsId = vtkm::CELL_SHAPE_EMPTY; @@ -103,7 +114,9 @@ public: this->ExpectedNumberOfCellsAdded = numCells; } - /// Second method to add cells -- one at a time. + /// @brief Add a cell. + /// + /// This can only be called after `AddCell`. template VTKM_CONT void AddCell(vtkm::UInt8 shapeId, vtkm::IdComponent numVertices, const IdVecType& ids) { @@ -154,9 +167,8 @@ public: this->Data->ConnectivityAdded += numVertices; } - /// Third and final method to add cells -- one at a time. - VTKM_CONT - void CompleteAddingCells(vtkm::Id numPoints) + /// @brief Finish adding cells one at a time. + VTKM_CONT void CompleteAddingCells(vtkm::Id numPoints) { this->Data->NumberOfPoints = numPoints; this->Data->CellPointIds.Connectivity.Allocate(this->Data->ConnectivityAdded, @@ -181,12 +193,14 @@ public: this->ExpectedNumberOfCellsAdded = -1; } - //This is the way you can fill the memory from another system without copying - VTKM_CONT - void Fill(vtkm::Id numPoints, - vtkm::UInt8 shapeId, - vtkm::IdComponent numberOfPointsPerCell, - const vtkm::cont::ArrayHandle& connectivity) + /// @brief Set all the cells of the mesh. + /// + /// This method can be used to fill the memory from another system without + /// copying data. + VTKM_CONT void Fill(vtkm::Id numPoints, + vtkm::UInt8 shapeId, + vtkm::IdComponent numberOfPointsPerCell, + const vtkm::cont::ArrayHandle& connectivity) { this->Data->NumberOfPoints = numPoints; this->CellShapeAsId = shapeId; diff --git a/vtkm/cont/CellSetStructured.h b/vtkm/cont/CellSetStructured.h index 96b3f5a7f..12b015769 100644 --- a/vtkm/cont/CellSetStructured.h +++ b/vtkm/cont/CellSetStructured.h @@ -23,6 +23,12 @@ namespace vtkm namespace cont { +/// @brief Defines a 1-, 2-, or 3-dimensional structured grid of points. +/// +/// The structured cells form lines, quadrilaterals, or hexahedra for 1-, 2-, or 3-dimensions, +/// respectively, to connect th epoints. +/// The topology is specified by simply providing the dimensions, which is the number of points +/// in the i, j, and k directions of the grid of points. template class VTKM_ALWAYS_EXPORT CellSetStructured final : public CellSet { @@ -35,8 +41,10 @@ public: using SchedulingRangeType = typename InternalsType::SchedulingRangeType; + /// @brief Get the number of cells in the topology. vtkm::Id GetNumberOfCells() const override { return this->Structure.GetNumberOfCells(); } + /// @brief Get the number of points in the topology. vtkm::Id GetNumberOfPoints() const override { return this->Structure.GetNumberOfPoints(); } vtkm::Id GetNumberOfFaces() const override { return -1; } @@ -46,6 +54,7 @@ public: // Since the entire topology is defined by by three integers, nothing to do here. void ReleaseResourcesExecution() override {} + /// @brief Set the dimensions of the structured array of points. void SetPointDimensions(SchedulingRangeType dimensions) { this->Structure.SetPointDimensions(dimensions); @@ -61,6 +70,7 @@ public: this->Structure.SetGlobalPointIndexStart(start); } + /// Get the dimensions of the points. SchedulingRangeType GetPointDimensions() const { return this->Structure.GetPointDimensions(); } SchedulingRangeType GetGlobalPointDimensions() const diff --git a/vtkm/cont/ConvertNumComponentsToOffsets.h b/vtkm/cont/ConvertNumComponentsToOffsets.h index 07286927e..1dd7850fd 100644 --- a/vtkm/cont/ConvertNumComponentsToOffsets.h +++ b/vtkm/cont/ConvertNumComponentsToOffsets.h @@ -22,21 +22,20 @@ namespace cont { -/// @{ /// `ConvertNumComponentsToOffsets` takes an array of Vec sizes (i.e. the number of components in /// each `Vec`) and returns an array of offsets to a packed array of such `Vec`s. The resulting /// array can be used with `ArrayHandleGroupVecVariable`. /// -/// \param numComponentsArray the input array that specifies the number of components in each group +/// @param[in] numComponentsArray the input array that specifies the number of components in each group /// Vec. /// -/// \param offsetsArray (optional) the output \c ArrayHandle, which must have a value type of \c +/// @param[out] offsetsArray (optional) the output \c ArrayHandle, which must have a value type of \c /// vtkm::Id. If the output \c ArrayHandle is not given, it is returned. /// -/// \param componentsArraySize (optional) a reference to a \c vtkm::Id and is filled with the +/// @param[in] componentsArraySize (optional) a reference to a \c vtkm::Id and is filled with the /// expected size of the component values array. /// -/// \param device (optional) specifies the device on which to run the conversion. +/// \param[in] device (optional) specifies the device on which to run the conversion. /// /// Note that this function is pre-compiled for some set of `ArrayHandle` types. If you get a /// warning about an inefficient conversion (or the operation fails outright), you might need to @@ -62,8 +61,6 @@ VTKM_CONT_EXPORT vtkm::cont::ArrayHandle ConvertNumComponentsToOffsets const vtkm::cont::UnknownArrayHandle& numComponentsArray, vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny{}); -/// @} - } // namespace vtkm::cont } // namespace vtkm diff --git a/vtkm/cont/CoordinateSystem.h b/vtkm/cont/CoordinateSystem.h index 72f454d7a..3026dfefc 100644 --- a/vtkm/cont/CoordinateSystem.h +++ b/vtkm/cont/CoordinateSystem.h @@ -22,6 +22,11 @@ namespace vtkm namespace cont { +/// @brief Manages a coordinate system for a `DataSet`. +/// +/// A coordinate system is really a field with a special meaning, so `CoordinateSystem` +/// class inherits from the `Field` class. `CoordinateSystem` constrains the field to +/// be associated with points and typically has 3D floating point vectors for values. class VTKM_CONT_EXPORT CoordinateSystem : public vtkm::cont::Field { using Superclass = vtkm::cont::Field; diff --git a/vtkm/cont/DataSet.h b/vtkm/cont/DataSet.h index c55a193b7..bc02d64ae 100644 --- a/vtkm/cont/DataSet.h +++ b/vtkm/cont/DataSet.h @@ -31,6 +31,29 @@ VTKM_CONT_EXPORT VTKM_CONT const std::string& GetGlobalGhostCellFieldName() noex VTKM_CONT_EXPORT VTKM_CONT void SetGlobalGhostCellFieldName(const std::string& name) noexcept; +/// @brief Contains and manages the geometric data structures that VTK-m operates on. +/// +/// A `DataSet` is the main data structure used by VTK-m to pass data in and out of +/// filters, rendering, and other components. A data set comprises the following 3 +/// data structures. +/// +/// * **CellSet** A cell set describes topological connections. A cell set defines some +/// number of points in space and how they connect to form cells, filled regions of +/// space. A data set has exactly one cell set. +/// * **Field** A field describes numerical data associated with the topological elements +/// in a cell set. The field is represented as an array, and each entry in the field +/// array corresponds to a topological element (point, edge, face, or cell). Together +/// the cell set topology and discrete data values in the field provide an interpolated +/// function throughout the volume of space covered by the data set. A cell set can +/// have any number of fields. +/// * **CoordinateSystem** A coordinate system is a special field that describes the +/// physical location of the points in a data set. Although it is most common for a +/// data set to contain a single coordinate system, VTK-m supports data sets with no +/// coordinate system such as abstract data structures like graphs that might not have +/// positions in a space. `DataSet` also supports multiple coordinate systems for data +/// that have multiple representations for position. For example, geospatial data could +/// simultaneously have coordinate systems defined by 3D position, latitude-longitude, +/// and any number of 2D projections. class VTKM_CONT_EXPORT DataSet { public: diff --git a/vtkm/cont/DataSetBuilderExplicit.h b/vtkm/cont/DataSetBuilderExplicit.h index a45c9eb46..68f7fe346 100644 --- a/vtkm/cont/DataSetBuilderExplicit.h +++ b/vtkm/cont/DataSetBuilderExplicit.h @@ -30,10 +30,24 @@ public: VTKM_CONT DataSetBuilderExplicit() {} - //Single cell explicits. - //TODO - - //Zoo explicit cell + /// \brief Create a 1D `DataSet` with arbitrary cell connectivity. + /// + /// The cell connectivity is specified with arrays defining the shape and point + /// connections of each cell. + /// In this form, the cell connectivity and coordinates are specified as `std::vector` + /// and the data will be copied to create the data object. + /// + /// @param[in] xVals An array providing the x coordinate of each point. + /// @param[in] shapes An array of shapes for each cell. Each entry should be one of the + /// `vtkm::CELL_SHAPE_*` values identifying the shape of the corresponding cell. + /// @param[in] numIndices An array containing for each cell the number of points incident + /// on that cell. + /// @param[in] connectivity An array specifying for each cell the indicies of points + /// incident on each cell. Each cell has a short array of indices that reference points + /// in the @a coords array. The length of each of these short arrays is specified by + /// the @a numIndices array. These variable length arrays are tightly packed together + /// in this @a connectivity array. + /// @param[in] coordsNm (optional) The name to register the coordinates as. template VTKM_CONT static vtkm::cont::DataSet Create(const std::vector& xVals, const std::vector& shapes, @@ -46,6 +60,25 @@ public: xVals, yVals, zVals, shapes, numIndices, connectivity, coordsNm); } + /// \brief Create a 2D `DataSet` with arbitrary cell connectivity. + /// + /// The cell connectivity is specified with arrays defining the shape and point + /// connections of each cell. + /// In this form, the cell connectivity and coordinates are specified as `std::vector` + /// and the data will be copied to create the data object. + /// + /// @param[in] xVals An array providing the x coordinate of each point. + /// @param[in] yVals An array providing the x coordinate of each point. + /// @param[in] shapes An array of shapes for each cell. Each entry should be one of the + /// `vtkm::CELL_SHAPE_*` values identifying the shape of the corresponding cell. + /// @param[in] numIndices An array containing for each cell the number of points incident + /// on that cell. + /// @param[in] connectivity An array specifying for each cell the indicies of points + /// incident on each cell. Each cell has a short array of indices that reference points + /// in the @a coords array. The length of each of these short arrays is specified by + /// the @a numIndices array. These variable length arrays are tightly packed together + /// in this @a connectivity array. + /// @param[in] coordsNm (optional) The name to register the coordinates as. template VTKM_CONT static vtkm::cont::DataSet Create(const std::vector& xVals, const std::vector& yVals, @@ -59,6 +92,26 @@ public: xVals, yVals, zVals, shapes, numIndices, connectivity, coordsNm); } + /// \brief Create a 3D `DataSet` with arbitrary cell connectivity. + /// + /// The cell connectivity is specified with arrays defining the shape and point + /// connections of each cell. + /// In this form, the cell connectivity and coordinates are specified as `std::vector` + /// and the data will be copied to create the data object. + /// + /// @param[in] xVals An array providing the x coordinate of each point. + /// @param[in] yVals An array providing the x coordinate of each point. + /// @param[in] zVals An array providing the x coordinate of each point. + /// @param[in] shapes An array of shapes for each cell. Each entry should be one of the + /// `vtkm::CELL_SHAPE_*` values identifying the shape of the corresponding cell. + /// @param[in] numIndices An array containing for each cell the number of points incident + /// on that cell. + /// @param[in] connectivity An array specifying for each cell the indicies of points + /// incident on each cell. Each cell has a short array of indices that reference points + /// in the @a coords array. The length of each of these short arrays is specified by + /// the @a numIndices array. These variable length arrays are tightly packed together + /// in this @a connectivity array. + /// @param[in] coordsNm (optional) The name to register the coordinates as. template VTKM_CONT static vtkm::cont::DataSet Create(const std::vector& xVals, const std::vector& yVals, @@ -68,6 +121,24 @@ public: const std::vector& connectivity, const std::string& coordsNm = "coords"); + /// \brief Create a 3D `DataSet` with arbitrary cell connectivity. + /// + /// The cell connectivity is specified with arrays defining the shape and point + /// connections of each cell. + /// In this form, the cell connectivity and coordinates are specified as `std::vector` + /// and the data will be copied to create the data object. + /// + /// @param[in] coords An array of point coordinates. + /// @param[in] shapes An array of shapes for each cell. Each entry should be one of the + /// `vtkm::CELL_SHAPE_*` values identifying the shape of the corresponding cell. + /// @param[in] numIndices An array containing for each cell the number of points incident + /// on that cell. + /// @param[in] connectivity An array specifying for each cell the indicies of points + /// incident on each cell. Each cell has a short array of indices that reference points + /// in the @a coords array. The length of each of these short arrays is specified by + /// the @a numIndices array. These variable length arrays are tightly packed together + /// in this @a connectivity array. + /// @param[in] coordsNm (optional) The name to register the coordinates as. template VTKM_CONT static vtkm::cont::DataSet Create(const std::vector>& coords, const std::vector& shapes, @@ -75,6 +146,25 @@ public: const std::vector& connectivity, const std::string& coordsNm = "coords"); + /// \brief Create a 3D `DataSet` with arbitrary cell connectivity. + /// + /// The cell connectivity is specified with arrays defining the shape and point + /// connections of each cell. + /// In this form, the cell connectivity and coordinates are specified as `ArrayHandle` + /// and the memory will be shared with the created data object. That said, the `DataSet` + /// construction will generate a new array for offsets. + /// + /// @param[in] coords An array of point coordinates. + /// @param[in] shapes An array of shapes for each cell. Each entry should be one of the + /// `vtkm::CELL_SHAPE_*` values identifying the shape of the corresponding cell. + /// @param[in] numIndices An array containing for each cell the number of points incident + /// on that cell. + /// @param[in] connectivity An array specifying for each cell the indicies of points + /// incident on each cell. Each cell has a short array of indices that reference points + /// in the @a coords array. The length of each of these short arrays is specified by + /// the @a numIndices array. These variable length arrays are tightly packed together + /// in this @a connectivity array. + /// @param[in] coordsNm (optional) The name to register the coordinates as. template VTKM_CONT static vtkm::cont::DataSet Create( const vtkm::cont::ArrayHandle>& coords, @@ -87,6 +177,27 @@ public: return DataSetBuilderExplicit::BuildDataSet(coords, shapes, offsets, connectivity, coordsNm); } + /// \brief Create a 3D `DataSet` with arbitrary cell connectivity for a single cell type. + /// + /// The cell connectivity is specified with an array defining the point + /// connections of each cell. + /// All the cells in the `DataSet` are of the same shape and contain the same number + /// of incident points. + /// In this form, the cell connectivity and coordinates are specified as `std::vector` + /// and the data will be copied to create the data object. + /// + /// @param[in] coords An array of point coordinates. + /// @param[in] tag A tag object representing the shape of all the cells in the mesh. + /// Cell shape tag objects have a name of the form `vtkm::CellShapeTag*` such as + /// `vtkm::CellShapeTagTriangle` or `vtkm::CellShapeTagHexahedron`. To specify a + /// cell shape determined at runtime, use `vtkm::CellShapeTagGeneric`. + /// @param[in] numberOfPointsPerCell The number of points that are incident to each cell. + /// @param[in] connectivity An array specifying for each cell the indicies of points + /// incident on each cell. Each cell has a short array of indices that reference points + /// in the @a coords array. The length of each of these short arrays is specified by + /// @a numberOfPointsPerCell. These short arrays are tightly packed together + /// in this @a connectivity array. + /// @param[in] coordsNm (optional) The name to register the coordinates as. template VTKM_CONT static vtkm::cont::DataSet Create(const std::vector>& coords, CellShapeTag tag, @@ -94,6 +205,27 @@ public: const std::vector& connectivity, const std::string& coordsNm = "coords"); + /// \brief Create a 3D `DataSet` with arbitrary cell connectivity for a single cell type. + /// + /// The cell connectivity is specified with an array defining the point + /// connections of each cell. + /// All the cells in the `DataSet` are of the same shape and contain the same number + /// of incident points. + /// In this form, the cell connectivity and coordinates are specified as `ArrayHandle` + /// and the memory will be shared with the created data object. + /// + /// @param[in] coords An array of point coordinates. + /// @param[in] tag A tag object representing the shape of all the cells in the mesh. + /// Cell shape tag objects have a name of the form `vtkm::CellShapeTag*` such as + /// `vtkm::CellShapeTagTriangle` or `vtkm::CellShapeTagHexahedron`. To specify a + /// cell shape determined at runtime, use `vtkm::CellShapeTagGeneric`. + /// @param[in] numberOfPointsPerCell The number of points that are incident to each cell. + /// @param[in] connectivity An array specifying for each cell the indicies of points + /// incident on each cell. Each cell has a short array of indices that reference points + /// in the @a coords array. The length of each of these short arrays is specified by + /// @a numberOfPointsPerCell. These short arrays are tightly packed together + /// in this @a connectivity array. + /// @param[in] coordsNm (optional) The name to register the coordinates as. template VTKM_CONT static vtkm::cont::DataSet Create( const vtkm::cont::ArrayHandle>& coords, @@ -231,27 +363,54 @@ inline VTKM_CONT vtkm::cont::DataSet DataSetBuilderExplicit::BuildDataSet( return dataSet; } +/// @brief Helper class to build a `DataSet` by iteratively adding points and cells. +/// +/// This class allows you to specify a `DataSet` by adding points and cells one at a time. class VTKM_CONT_EXPORT DataSetBuilderExplicitIterative { public: - VTKM_CONT - DataSetBuilderExplicitIterative(); + VTKM_CONT DataSetBuilderExplicitIterative(); - VTKM_CONT - void Begin(const std::string& coordName = "coords"); + /// @brief Begin defining points and cells of a `DataSet`. + /// + /// The state of this object is initialized to be ready to use `AddPoint` and + /// `AddCell` methods. + /// + /// @param[in] coordName (optional) The name to register the coordinates as. + VTKM_CONT void Begin(const std::string& coordName = "coords"); - //Define points. - VTKM_CONT - vtkm::cont::DataSet Create(); + /// @brief Add a point to the `DataSet`. + /// + /// @param[in] pt The coordinates of the point to add. + /// @returns The index of the newly created point. + VTKM_CONT vtkm::Id AddPoint(const vtkm::Vec3f& pt); - VTKM_CONT - vtkm::Id AddPoint(const vtkm::Vec3f& pt); + /// @brief Add a point to the `DataSet`. + /// + /// @param[in] pt The coordinates of the point to add. + /// @returns The index of the newly created point. + template + VTKM_CONT vtkm::Id AddPoint(const vtkm::Vec& pt) + { + return AddPoint(static_cast(pt)); + } - VTKM_CONT - vtkm::Id AddPoint(const vtkm::FloatDefault& x, - const vtkm::FloatDefault& y, - const vtkm::FloatDefault& z = 0); + /// @brief Add a point to the `DataSet`. + /// + /// @param[in] x The x coordinate of the newly created point. + /// @param[in] y The y coordinate of the newly created point. + /// @param[in] z The z coordinate of the newly created point. + /// @returns The index of the newly created point. + VTKM_CONT vtkm::Id AddPoint(const vtkm::FloatDefault& x, + const vtkm::FloatDefault& y, + const vtkm::FloatDefault& z = 0); + /// @brief Add a point to the `DataSet`. + /// + /// @param[in] x The x coordinate of the newly created point. + /// @param[in] y The y coordinate of the newly created point. + /// @param[in] z The z coordinate of the newly created point. + /// @returns The index of the newly created point. template VTKM_CONT vtkm::Id AddPoint(const T& x, const T& y, const T& z = 0) { @@ -260,24 +419,41 @@ public: static_cast(z)); } - template - VTKM_CONT vtkm::Id AddPoint(const vtkm::Vec& pt) - { - return AddPoint(static_cast(pt)); - } + /// @brief Add a cell to the `DataSet`. + /// + /// @param[in] shape Identifies the shape of the cell. Use one of the + /// `vtkm::CELL_SHAPE_*` values. + /// @param[in] conn List of indices to the incident points. + VTKM_CONT void AddCell(const vtkm::UInt8& shape, const std::vector& conn); - //Define cells. - VTKM_CONT - void AddCell(vtkm::UInt8 shape); + /// @brief Add a cell to the `DataSet`. + /// + /// @param[in] shape Identifies the shape of the cell. Use one of the + /// `vtkm::CELL_SHAPE_*` values. + /// @param[in] conn List of indices to the incident points. + /// @param[in] n The number of incident points (and the length of the `conn` array). + VTKM_CONT void AddCell(const vtkm::UInt8& shape, + const vtkm::Id* conn, + const vtkm::IdComponent& n); - VTKM_CONT - void AddCell(const vtkm::UInt8& shape, const std::vector& conn); + /// @brief Start adding a cell to the `DataSet`. + /// + /// The incident points are later added one at a time using `AddCellPoint`. + /// The cell is completed the next time `AddCell` or `Create` is called. + /// + /// @param[in] shape Identifies the shape of the cell. Use one of the + VTKM_CONT void AddCell(vtkm::UInt8 shape); - VTKM_CONT - void AddCell(const vtkm::UInt8& shape, const vtkm::Id* conn, const vtkm::IdComponent& n); + /// @brief Add an incident point to the current cell. + /// + /// @param[in] pointIndex Index to the incident point. + VTKM_CONT void AddCellPoint(vtkm::Id pointIndex); - VTKM_CONT - void AddCellPoint(vtkm::Id pointIndex); + /// @brief Produce the `DataSet`. + /// + /// The points and cells previously added are finalized and the resulting `DataSet` + /// is returned. + VTKM_CONT vtkm::cont::DataSet Create(); private: std::string coordNm; diff --git a/vtkm/cont/DataSetBuilderRectilinear.h b/vtkm/cont/DataSetBuilderRectilinear.h index d8a716bd4..67b5447db 100644 --- a/vtkm/cont/DataSetBuilderRectilinear.h +++ b/vtkm/cont/DataSetBuilderRectilinear.h @@ -49,7 +49,15 @@ public: VTKM_CONT DataSetBuilderRectilinear(); - //1D grids. + /// @brief Create a 1D retilinear `DataSet`. + /// + /// A rectilinear grid is specified with a scalar array for the point coordinates + /// in the x direction. + /// In this form, the coordinate array is specified with `std::vector`. + /// The data is copied from the `std::vector`. + /// + /// @param[in] xvals An array of coordinates to use along the x dimension. + /// @param[in] coordNm (optional) The name to register the coordinates as. template VTKM_CONT static vtkm::cont::DataSet Create(const std::vector& xvals, const std::string& coordNm = "coords") @@ -58,6 +66,16 @@ public: return DataSetBuilderRectilinear::BuildDataSet(xvals, yvals, zvals, coordNm); } + /// @brief Create a 1D retilinear `DataSet`. + /// + /// A rectilinear grid is specified with a scalar array for the point coordinates + /// in the x direction. + /// In this form, the coordinate array is specified with a standard C array. + /// The data is copied from the array. + /// + /// @param[in] nx The size of the grid in the x direction (and length of the @a xvals array). + /// @param[in] xvals An array of coordinates to use along the x dimension. + /// @param[in] coordNm (optional) The name to register the coordinates as. template VTKM_CONT static vtkm::cont::DataSet Create(vtkm::Id nx, T* xvals, @@ -67,6 +85,16 @@ public: return DataSetBuilderRectilinear::BuildDataSet(nx, 1, 1, xvals, &yvals, &zvals, coordNm); } + /// @brief Create a 1D retilinear `DataSet`. + /// + /// A rectilinear grid is specified with a scalar array for the point coordinates + /// in the x direction. + /// In this form, the coordinate array is specified with `vtkm::cont::ArrayHandle`. + /// The `ArrayHandle` is shared with the `DataSet`, so changing the `ArrayHandle` + /// changes the `DataSet`. + /// + /// @param[in] xvals An array of coordinates to use along the x dimension. + /// @param[in] coordNm (optional) The name to register the coordinates as. template VTKM_CONT static vtkm::cont::DataSet Create(const vtkm::cont::ArrayHandle& xvals, const std::string& coordNm = "coords") @@ -79,7 +107,16 @@ public: return DataSetBuilderRectilinear::BuildDataSet(xvals, yvals, zvals, coordNm); } - //2D grids. + /// @brief Create a 2D retilinear `DataSet`. + /// + /// A rectilinear grid is specified with separate arrays for the point coordinates + /// in the x and y directions. + /// In this form, the coordinate arrays are specified with `std::vector`. + /// The data is copied from the `std::vector`s. + /// + /// @param[in] xvals An array of coordinates to use along the x dimension. + /// @param[in] yvals An array of coordinates to use along the x dimension. + /// @param[in] coordNm (optional) The name to register the coordinates as. template VTKM_CONT static vtkm::cont::DataSet Create(const std::vector& xvals, const std::vector& yvals, @@ -89,6 +126,18 @@ public: return DataSetBuilderRectilinear::BuildDataSet(xvals, yvals, zvals, coordNm); } + /// @brief Create a 2D retilinear `DataSet`. + /// + /// A rectilinear grid is specified with separate arrays for the point coordinates + /// in the x and y directions. + /// In this form, the coordinate arrays are specified with standard C arrays. + /// The data is copied from the arrays. + /// + /// @param[in] nx The size of the grid in the x direction (and length of the @a xvals array). + /// @param[in] ny The size of the grid in the x direction (and length of the @a yvals array). + /// @param[in] xvals An array of coordinates to use along the x dimension. + /// @param[in] yvals An array of coordinates to use along the x dimension. + /// @param[in] coordNm (optional) The name to register the coordinates as. template VTKM_CONT static vtkm::cont::DataSet Create(vtkm::Id nx, vtkm::Id ny, @@ -100,6 +149,17 @@ public: return DataSetBuilderRectilinear::BuildDataSet(nx, ny, 1, xvals, yvals, &zvals, coordNm); } + /// @brief Create a 2D retilinear `DataSet`. + /// + /// A rectilinear grid is specified with separate arrays for the point coordinates + /// in the x and y directions. + /// In this form, the coordinate arrays are specified with `vtkm::cont::ArrayHandle`. + /// The `ArrayHandle`s are shared with the `DataSet`, so changing the `ArrayHandle`s + /// changes the `DataSet`. + /// + /// @param[in] xvals An array of coordinates to use along the x dimension. + /// @param[in] yvals An array of coordinates to use along the x dimension. + /// @param[in] coordNm (optional) The name to register the coordinates as. template VTKM_CONT static vtkm::cont::DataSet Create(const vtkm::cont::ArrayHandle& xvals, const vtkm::cont::ArrayHandle& yvals, @@ -111,7 +171,20 @@ public: return DataSetBuilderRectilinear::BuildDataSet(xvals, yvals, zvals, coordNm); } - //3D grids. + /// @brief Create a 3D retilinear `DataSet`. + /// + /// A rectilinear grid is specified with separate arrays for the point coordinates + /// in the x, y, and z directions. + /// In this form, the coordinate arrays are specified with standard C arrays. + /// The data is copied from the arrays. + /// + /// @param[in] nx The size of the grid in the x direction (and length of the @a xvals array). + /// @param[in] ny The size of the grid in the x direction (and length of the @a yvals array). + /// @param[in] nz The size of the grid in the x direction (and length of the @a zvals array). + /// @param[in] xvals An array of coordinates to use along the x dimension. + /// @param[in] yvals An array of coordinates to use along the x dimension. + /// @param[in] zvals An array of coordinates to use along the x dimension. + /// @param[in] coordNm (optional) The name to register the coordinates as. template VTKM_CONT static vtkm::cont::DataSet Create(vtkm::Id nx, vtkm::Id ny, @@ -124,6 +197,17 @@ public: return DataSetBuilderRectilinear::BuildDataSet(nx, ny, nz, xvals, yvals, zvals, coordNm); } + /// @brief Create a 3D retilinear `DataSet`. + /// + /// A rectilinear grid is specified with separate arrays for the point coordinates + /// in the x, y, and z directions. + /// In this form, the coordinate arrays are specified with `std::vector`. + /// The data is copied from the `std::vector`s. + /// + /// @param[in] xvals An array of coordinates to use along the x dimension. + /// @param[in] yvals An array of coordinates to use along the x dimension. + /// @param[in] zvals An array of coordinates to use along the x dimension. + /// @param[in] coordNm (optional) The name to register the coordinates as. template VTKM_CONT static vtkm::cont::DataSet Create(const std::vector& xvals, const std::vector& yvals, @@ -133,6 +217,18 @@ public: return DataSetBuilderRectilinear::BuildDataSet(xvals, yvals, zvals, coordNm); } + /// @brief Create a 3D retilinear `DataSet`. + /// + /// A rectilinear grid is specified with separate arrays for the point coordinates + /// in the x, y, and z directions. + /// In this form, the coordinate arrays are specified with `vtkm::cont::ArrayHandle`. + /// The `ArrayHandle`s are shared with the `DataSet`, so changing the `ArrayHandle`s + /// changes the `DataSet`. + /// + /// @param[in] xvals An array of coordinates to use along the x dimension. + /// @param[in] yvals An array of coordinates to use along the x dimension. + /// @param[in] zvals An array of coordinates to use along the x dimension. + /// @param[in] coordNm (optional) The name to register the coordinates as. template VTKM_CONT static vtkm::cont::DataSet Create(const vtkm::cont::ArrayHandle& xvals, const vtkm::cont::ArrayHandle& yvals, diff --git a/vtkm/cont/DataSetBuilderUniform.h b/vtkm/cont/DataSetBuilderUniform.h index 0aa5440d2..4740cc721 100644 --- a/vtkm/cont/DataSetBuilderUniform.h +++ b/vtkm/cont/DataSetBuilderUniform.h @@ -26,7 +26,14 @@ public: VTKM_CONT DataSetBuilderUniform(); - //1D uniform grid + /// @brief Create a 1D uniform `DataSet`. + /// + /// @param[in] dimension The size of the grid. The dimensions are specified + /// based on the number of points (as opposed to the number of cells). + /// @param[in] origin The origin of the data. This is the point coordinate with + /// the minimum value in all dimensions. + /// @param[in] spacing The uniform distance between adjacent points. + /// @param[in] coordNm (optional) The name to register the coordinates as. template VTKM_CONT static vtkm::cont::DataSet Create(const vtkm::Id& dimension, const T& origin, @@ -40,11 +47,24 @@ public: coordNm); } - VTKM_CONT - static vtkm::cont::DataSet Create(const vtkm::Id& dimension, - const std::string& coordNm = "coords"); + /// @brief Create a 1D uniform `DataSet`. + /// + /// The origin is set to 0 and the spacing is set to 1. + /// + /// @param[in] dimension The size of the grid. The dimensions are specified + /// based on the number of points (as opposed to the number of cells). + /// @param[in] coordNm (optional) The name to register the coordinates as. + VTKM_CONT static vtkm::cont::DataSet Create(const vtkm::Id& dimension, + const std::string& coordNm = "coords"); - //2D uniform grids. + /// @brief Create a 2D uniform `DataSet`. + /// + /// @param[in] dimensions The size of the grid. The dimensions are specified + /// based on the number of points (as opposed to the number of cells). + /// @param[in] origin The origin of the data. This is the point coordinate with + /// the minimum value in all dimensions. + /// @param[in] spacing The uniform distance between adjacent points. + /// @param[in] coordNm (optional) The name to register the coordinates as. template VTKM_CONT static vtkm::cont::DataSet Create(const vtkm::Id2& dimensions, const vtkm::Vec& origin, @@ -61,11 +81,24 @@ public: coordNm); } - VTKM_CONT - static vtkm::cont::DataSet Create(const vtkm::Id2& dimensions, - const std::string& coordNm = "coords"); + /// @brief Create a 2D uniform `DataSet`. + /// + /// The origin is set to (0,0) and the spacing is set to (1,1). + /// + /// @param[in] dimensions The size of the grid. The dimensions are specified + /// based on the number of points (as opposed to the number of cells). + /// @param[in] coordNm (optional) The name to register the coordinates as. + VTKM_CONT static vtkm::cont::DataSet Create(const vtkm::Id2& dimensions, + const std::string& coordNm = "coords"); - //3D uniform grids. + /// @brief Create a 3D uniform `DataSet`. + /// + /// @param[in] dimensions The size of the grid. The dimensions are specified + /// based on the number of points (as opposed to the number of cells). + /// @param[in] origin The origin of the data. This is the point coordinate with + /// the minimum value in all dimensions. + /// @param[in] spacing The uniform distance between adjacent points. + /// @param[in] coordNm (optional) The name to register the coordinates as. template VTKM_CONT static vtkm::cont::DataSet Create(const vtkm::Id3& dimensions, const vtkm::Vec& origin, @@ -83,9 +116,15 @@ public: coordNm); } - VTKM_CONT - static vtkm::cont::DataSet Create(const vtkm::Id3& dimensions, - const std::string& coordNm = "coords"); + /// @brief Create a 3D uniform `DataSet`. + /// + /// The origin is set to (0,0,0) and the spacing is set to (1,1,1). + /// + /// @param[in] dimensions The size of the grid. The dimensions are specified + /// based on the number of points (as opposed to the number of cells). + /// @param[in] coordNm (optional) The name to register the coordinates as. + VTKM_CONT static vtkm::cont::DataSet Create(const vtkm::Id3& dimensions, + const std::string& coordNm = "coords"); private: VTKM_CONT diff --git a/vtkm/cont/DeviceAdapterTag.h b/vtkm/cont/DeviceAdapterTag.h index 93ebbdf55..9b5712d19 100644 --- a/vtkm/cont/DeviceAdapterTag.h +++ b/vtkm/cont/DeviceAdapterTag.h @@ -49,19 +49,41 @@ namespace cont using DeviceAdapterNameType = std::string; +/// @brief An object used to specify a device. +/// +/// `vtkm::cont::DeviceAdapterId` can be used to specify a device to use when +/// executing some code. Each `DeviceAdapterTag` object inherits from +/// `vtkm::cont::DeviceAdapterId`. Functions can accept a `vtkm::cont::DeviceAdapterId` +/// object rather than a templated tag to select a device adapter at runtime. struct DeviceAdapterId { constexpr bool operator==(DeviceAdapterId other) const { return this->Value == other.Value; } constexpr bool operator!=(DeviceAdapterId other) const { return this->Value != other.Value; } constexpr bool operator<(DeviceAdapterId other) const { return this->Value < other.Value; } + /// @brief Return whether this object represents a valid type of device. + /// + /// This method will return true if the id represents a specific, valid device. + /// It will return true even if the device is disabled in by the runtime tracker + /// or if the device is not supported by the VTK-m build configuration. + /// + /// It should be noted that this method return false for tags that are not specific + /// devices. This includes `vtkm::cont::DeviceAdapterTagAny` and + /// `vtkm::cont::DeviceAdapterTagUndefined`. constexpr bool IsValueValid() const { return this->Value > 0 && this->Value < VTKM_MAX_DEVICE_ADAPTER_ID; } + /// @brief Returns the numeric value of the index. constexpr vtkm::Int8 GetValue() const { return this->Value; } + /// @brief Return a name representing the device. + /// + /// The string returned from this method is stored in a type named + /// `vtkm::cont::DeviceAdapterNameType`, which is currently aliased to + /// `std::string`. The device adapter name is useful for printing information + /// about a device being used. VTKM_CONT_EXPORT DeviceAdapterNameType GetName() const; @@ -149,11 +171,19 @@ struct DeviceAdapterTraits; } \ } -// Represents when using TryExecute that the functor -// can be executed on any device instead of a specific -// one +/// @struct vtkm::cont::DeviceAdapterTagAny +/// @brief Tag for a device adapter used to specify that any device may be used +/// for an operation. +/// +/// In practice this is limited to devices that are currently available. + VTKM_VALID_DEVICE_ADAPTER(Any, VTKM_DEVICE_ADAPTER_ANY) +/// @struct vtkm::cont::DeviceAdapterTagUndefined +/// @brief Tag for a device adapter used to avoid specifying a device. +/// +/// Useful as a placeholder when a device can be specified but none is given. + VTKM_INVALID_DEVICE_ADAPTER(Undefined, VTKM_DEVICE_ADAPTER_UNDEFINED) /// Checks that the argument is a proper device adapter tag. This is a handy diff --git a/vtkm/cont/Error.h b/vtkm/cont/Error.h index 9929fcfbf..aa636a1a8 100644 --- a/vtkm/cont/Error.h +++ b/vtkm/cont/Error.h @@ -35,8 +35,10 @@ class VTKM_ALWAYS_EXPORT Error : public std::exception public: //See note about GetMessage macro below. #ifndef GetMessage + /// @brief Returns a message describing what caused the error. const std::string& GetMessage() const { return this->Message; } #endif + /// @brief Provides a stack trace to the location where this error was thrown. const std::string& GetStackTrace() const { return this->StackTrace; } //GetMessage is a macro defined by to redirrect to @@ -47,7 +49,9 @@ public: const std::string& GetMessageW() const { return this->Message; } #endif - // For std::exception compatibility: + /// @brief Returns the message for the error and the stack trace for it. + /// + /// This method is provided for `std::exception` compatibility. const char* what() const noexcept override { return this->What.c_str(); } /// Returns true if this exception is device independent. For exceptions that diff --git a/vtkm/cont/Field.h b/vtkm/cont/Field.h index 8ec7e1a25..45990e4ba 100644 --- a/vtkm/cont/Field.h +++ b/vtkm/cont/Field.h @@ -31,8 +31,13 @@ namespace cont class VTKM_CONT_EXPORT Field { public: + /// @brief Identifies what elements of a data set a field is associated with. + /// + /// The `Association` enum is used by `vtkm::cont::Field` to specify on what + /// topological elements each item in the field is associated with. enum struct Association { + // Documentation is below (for better layout in generated documents). Any, WholeDataSet, Points, @@ -41,6 +46,49 @@ public: Global, }; + /// @var Association Any + /// @brief Any field regardless of the association. + /// + /// This is used when choosing a `vtkm::cont::Field` that could be of any + /// association. It is often used as the default if no association is given. + + /// @var Association WholeDataSet + /// @brief A "global" field that applies to the entirety of a `vtkm::cont::DataSet`. + /// + /// Fields of this association often contain summary or annotation information. + /// An example of a whole data set field could be the region that the mesh covers. + + /// @var Association Points + /// @brief A field that applies to points. + /// + /// There is a separate field value attached to each point. Point fields usually represent + /// samples of continuous data that can be reinterpolated through cells. Physical properties + /// such as temperature, pressure, density, velocity, etc. are usually best represented in + /// point fields. Data that deals with the points of the topology, such as displacement + /// vectors, are also appropriate for point data. + + /// @var Association Cells + /// @brief A field that applies to cells. + /// + /// There is a separate field value attached to each cell in a cell set. Cell fields + /// usually represent values from an integration over the finite cells of the mesh. + /// Integrated values like mass or volume are best represented in cell fields. Statistics + /// about each cell like strain or cell quality are also appropriate for cell data. + + /// @var Association Partitions + /// @brief A field that applies to partitions. + /// + /// This type of field is attached to a `vtkm::cont::PartitionedDataSet`. There is a + /// separate field value attached to each partition. Identification or information + /// about the arrangement of partitions such as hierarchy levels are usually best + /// represented in partition fields. + + /// @var Association Global + /// @brief A field that applies to all partitions. + /// + /// This type of field is attached to a `vtkm::cont::PartitionedDataSet`. It contains + /// values that are "global" across all partitions and data therin. + VTKM_CONT Field() = default; @@ -86,6 +134,14 @@ public: const vtkm::cont::UnknownArrayHandle& GetData() const; vtkm::cont::UnknownArrayHandle& GetData(); + /// @brief Returns the range of each component in the field array. + /// + /// The ranges of each component are returned in an `ArrayHandle` containing `vtkm::Range` + /// values. + /// So, for example, calling `GetRange` on a scalar field will return an `ArrayHandle` + /// with exactly 1 entry in it. Calling `GetRange` on a field of 3D vectors will return + /// an `ArrayHandle` with exactly 3 entries corresponding to each of the components in + /// the range. VTKM_CONT const vtkm::cont::ArrayHandle& GetRange() const; VTKM_CONT void GetRange(vtkm::Range* range) const; diff --git a/vtkm/cont/Initialize.h b/vtkm/cont/Initialize.h index a08daf6c1..2ac6db4cc 100644 --- a/vtkm/cont/Initialize.h +++ b/vtkm/cont/Initialize.h @@ -25,41 +25,50 @@ namespace cont struct InitializeResult { - /// Device passed into --vtkm-device, or undefined + /// The device passed into `--vtkm-device` argument. If no device was specified, then + /// this value is set to `DeviceAdapterTagUndefined`. Note that if the user specifies + /// "any" device, then this value can be set to `DeviceAdapterTagAny`, which is a + /// pseudo-tag that allows any supported device. DeviceAdapterId Device = DeviceAdapterTagUndefined{}; - /// Usage statement for arguments parsed by VTK-m + /// A usage statement for arguments parsed by VTK-m. If the calling code wants to print + /// a usage statement documenting the options that can be provided on the command line, + /// then this string can be added to document the options supported by VTK-m. std::string Usage; }; enum class InitializeOptions { + /// Placeholder used when no options are enabled. This is the value used when the third argument + /// to `vtkm::cont::Initialize` is not provided. None = 0x00, /// Issue an error if the device argument is not specified. RequireDevice = 0x01, - /// If no device is specified, treat it as if the user gave --vtkm-device=Any. This means that - /// DeviceAdapterTagUndefined will never be return in the result. + /// If no device is specified, treat it as if the user gave `--vtkm-device=Any`. This means that + /// `DeviceAdapterTagUndefined` will never be returned in the result. DefaultAnyDevice = 0x02, - /// Add a help argument. If -h or --vtkm-help is provided, prints a usage statement. Of course, - /// the usage statement will only print out arguments processed by VTK-m. + /// Add a help argument. If `-h` or `--vtkm-help` is provided, prints a usage statement. Of course, + /// the usage statement will only print out arguments processed by VTK-m, which is why help is not + /// given by default. Alternatively, a string with usage help is returned from `vtkm::cont::Initialize` + /// so that the calling program can provide VTK-m's help in its own usage statement. AddHelp = 0x04, /// If an unknown option is encountered, the program terminates with an error and a usage /// statement is printed. If this option is not provided, any unknown options are returned - /// in argv. If this option is used, it is a good idea to use AddHelp as well. + /// in `argv`. If this option is used, it is a good idea to use AddHelp as well. ErrorOnBadOption = 0x08, /// If an extra argument is encountered, the program terminates with an error and a usage /// statement is printed. If this option is not provided, any unknown arguments are returned - /// in argv. + /// in `argv`. ErrorOnBadArgument = 0x10, /// If supplied, Initialize treats its own arguments as the only ones supported by the /// application and provides an error if not followed exactly. This is a convenience - /// option that is a combination of ErrorOnBadOption, ErrorOnBadArgument, and AddHelp. + /// option that is a combination of `ErrorOnBadOption`, `ErrorOnBadArgument`, and `AddHelp`. Strict = ErrorOnBadOption | ErrorOnBadArgument | AddHelp }; @@ -79,14 +88,14 @@ inline InitializeOptions operator&(const InitializeOptions& lhs, const Initializ * Initialize the VTKm library, parsing arguments when provided: * - Sets log level names when logging is configured. * - Sets the calling thread as the main thread for logging purposes. - * - Sets the default log level to the argument provided to --vtkm-log-level. - * - Forces usage of the device name passed to --vtkm-device. - * - Prints usage when -h or --vtkm-help is passed. + * - Sets the default log level to the argument provided to `--vtkm-log-level`. + * - Forces usage of the device name passed to `--vtkm-device`. + * - Prints usage when `-h` or `--vtkm-help` is passed. * * The parameterless version only sets up log level names. * * Additional options may be supplied via the @a opts argument, such as - * requiring the --vtkm-device option. + * requiring the `--vtkm-device` option. * * Results are available in the returned InitializeResult. * diff --git a/vtkm/cont/Logging.h b/vtkm/cont/Logging.h index 2f1f22746..2894f78bc 100644 --- a/vtkm/cont/Logging.h +++ b/vtkm/cont/Logging.h @@ -496,6 +496,8 @@ inline VTKM_CONT std::string TypeToString(const T&) * * \param level Desired LogLevel value for the log message. * \param cond When false this function is no-op. + * \param file The source file where the log entry was genearted. + * \param line The line in the source file where the log entry was generated. * \param format Printf like format string. */ VTKM_CONT_EXPORT diff --git a/vtkm/cont/PartitionedDataSet.h b/vtkm/cont/PartitionedDataSet.h index 4a5917933..51421acfe 100644 --- a/vtkm/cont/PartitionedDataSet.h +++ b/vtkm/cont/PartitionedDataSet.h @@ -22,6 +22,7 @@ namespace vtkm namespace cont { +/// @brief Comprises a set of `vtkm::cont::DataSet` objects. class VTKM_CONT_EXPORT PartitionedDataSet { using StorageVec = std::vector; @@ -65,34 +66,35 @@ public: const vtkm::cont::DataSet& GetPartition(vtkm::Id partId) const; /// Get an STL vector of all DataSet objects stored in PartitionedDataSet. - VTKM_CONT - const std::vector& GetPartitions() const; + VTKM_CONT const std::vector& GetPartitions() const; - /// Add DataSet @a ds to the end of the contained DataSet vector. - VTKM_CONT - void AppendPartition(const vtkm::cont::DataSet& ds); + /// Add DataSet @a ds to the end of the list of partitions. + VTKM_CONT void AppendPartition(const vtkm::cont::DataSet& ds); - /// Add DataSet @a ds to position @a index of the contained DataSet vector. - VTKM_CONT - void InsertPartition(vtkm::Id index, const vtkm::cont::DataSet& ds); + /// @brief Add DataSet @a ds to position @a index of the contained DataSet vector. + /// + /// All partitions at or after this location are pushed back. + VTKM_CONT void InsertPartition(vtkm::Id index, const vtkm::cont::DataSet& ds); /// Replace the @a index positioned element of the contained DataSet vector /// with @a ds. - VTKM_CONT - void ReplacePartition(vtkm::Id index, const vtkm::cont::DataSet& ds); + VTKM_CONT void ReplacePartition(vtkm::Id index, const vtkm::cont::DataSet& ds); - /// Append the DataSet vector @a partitions to the end of the contained one. - VTKM_CONT - void AppendPartitions(const std::vector& partitions); + /// Append the DataSet vector @a partitions to the end of list of partitions. + /// + /// This list can be provided as a `std::vector`, or it can be an initializer + /// list (declared in `{ }` curly braces). + VTKM_CONT void AppendPartitions(const std::vector& partitions); - ///@{ /// Methods to Add and Get fields on a PartitionedDataSet - VTKM_CONT - vtkm::IdComponent GetNumberOfFields() const { return this->Fields.GetNumberOfFields(); } + VTKM_CONT vtkm::IdComponent GetNumberOfFields() const { return this->Fields.GetNumberOfFields(); } - //Fields on partitions. + /// @brief Adds a field that is applied to the meta-partition structure. + /// + /// The @a field must have a partition that applies across all partitions. VTKM_CONT void AddField(const Field& field) { this->Fields.AddField(field); } + /// @brief Add a field with a global association. template VTKM_CONT void AddGlobalField(const std::string& fieldName, const vtkm::cont::ArrayHandle& field) @@ -114,6 +116,7 @@ public: make_Field(fieldName, vtkm::cont::Field::Association::Global, field, n, vtkm::CopyFlag::On)); } + /// @brief Add a field where each entry is associated with a whole partition. template VTKM_CONT void AddPartitionsField(const std::string& fieldName, const vtkm::cont::ArrayHandle& field) @@ -149,6 +152,9 @@ public: return this->Fields.GetField(name, assoc); } + /// @brief Get a field associated with the partitioned data structure. + /// + /// The field is selected by name and, optionally, the association. VTKM_CONT vtkm::cont::Field& GetField( const std::string& name, @@ -157,12 +163,14 @@ public: return this->Fields.GetField(name, assoc); } + /// @brief Get a global field. VTKM_CONT const vtkm::cont::Field& GetGlobalField(const std::string& name) const { return this->GetField(name, vtkm::cont::Field::Association::Global); } + /// @brief Get a field associated with the partitions. VTKM_CONT const vtkm::cont::Field& GetPartitionsField(const std::string& name) const { @@ -181,6 +189,7 @@ public: return this->GetField(name, vtkm::cont::Field::Association::Partitions); } + /// @brief Query whether the partitioned data set has the named field. VTKM_CONT bool HasField(const std::string& name, vtkm::cont::Field::Association assoc = vtkm::cont::Field::Association::Any) const @@ -188,18 +197,17 @@ public: return this->Fields.HasField(name, assoc); } - VTKM_CONT - bool HasGlobalField(const std::string& name) const + /// @brief Query whether the partitioned data set has the named global field. + VTKM_CONT bool HasGlobalField(const std::string& name) const { return (this->Fields.GetFieldIndex(name, vtkm::cont::Field::Association::Global) != -1); } - VTKM_CONT - bool HasPartitionsField(const std::string& name) const + /// @brief Query whether the partitioned data set has the named partition field. + VTKM_CONT bool HasPartitionsField(const std::string& name) const { return (this->Fields.GetFieldIndex(name, vtkm::cont::Field::Association::Partitions) != -1); } - ///@} /// Copies the partitions from the source. The fields on the PartitionedDataSet are not copied. VTKM_CONT @@ -208,8 +216,11 @@ public: VTKM_CONT void PrintSummary(std::ostream& stream) const; - ///@{ - /// API to support range-based for loops on partitions. + /// @name Iterators + /// + /// `PartitionedDataSet` provides an iterator interface that allows you to iterate + /// over the contained partitions using the `for (auto ds : pds)` syntax. + /// @{ VTKM_CONT iterator begin() noexcept { return this->Partitions.begin(); } VTKM_CONT @@ -222,7 +233,7 @@ public: const_iterator cbegin() const noexcept { return this->Partitions.cbegin(); } VTKM_CONT const_iterator cend() const noexcept { return this->Partitions.cend(); } - ///@} + /// @} private: std::vector Partitions; diff --git a/vtkm/cont/RuntimeDeviceTracker.h b/vtkm/cont/RuntimeDeviceTracker.h index c847ec92a..57d0bc692 100644 --- a/vtkm/cont/RuntimeDeviceTracker.h +++ b/vtkm/cont/RuntimeDeviceTracker.h @@ -29,7 +29,7 @@ namespace detail struct RuntimeDeviceTrackerInternals; } -struct ScopedRuntimeDeviceTracker; +class ScopedRuntimeDeviceTracker; /// RuntimeDeviceTracker is the central location for determining /// which device adapter will be active for algorithm execution. @@ -76,7 +76,7 @@ public: /// Reset the tracker for the given device. This will discard any updates /// caused by reported failures. Passing DeviceAdapterTagAny to this will - /// reset all devices ( same as \c Reset ). + /// reset all devices (same as `Reset()`). /// VTKM_CONT void ResetDevice(vtkm::cont::DeviceAdapterId deviceId); @@ -86,12 +86,12 @@ public: VTKM_CONT void Reset(); - /// \brief Disable the given device. + /// @brief Disable the given device. /// - /// The main intention of \c RuntimeDeviceTracker is to keep track of what + /// The main intention of `RuntimeDeviceTracker` is to keep track of what /// devices are working for VTK-m. However, it can also be used to turn /// devices on and off. Use this method to disable (turn off) a given device. - /// Use \c ResetDevice to turn the device back on (if it is supported). + /// Use `ResetDevice()` to turn the device back on (if it is supported). /// /// Passing DeviceAdapterTagAny to this will disable all devices. /// @@ -99,47 +99,48 @@ public: /// \brief Disable all devices except the specified one. /// - /// The main intention of \c RuntimeDeviceTracker is to keep track of what + /// The main intention of `RuntimeDeviceTracker` is to keep track of what /// devices are working for VTK-m. However, it can also be used to turn /// devices on and off. Use this method to disable all devices except one /// to effectively force VTK-m to use that device. Either pass the - /// DeviceAdapterTagAny to this function or call \c Reset to restore + /// DeviceAdapterTagAny to this function or call `Reset()` to restore /// all devices to their default state. /// - /// This method will throw a \c ErrorBadValue if the given device does not - /// exist on the system. + /// This method will throw a `vtkm::cont::ErrorBadValue` if the given device + /// does not exist on the system. /// VTKM_CONT void ForceDevice(DeviceAdapterId deviceId); - /// \brief Get/Set use of thread-friendly memory allocation for a device. + /// @brief Get/Set use of thread-friendly memory allocation for a device. /// /// VTKM_CONT bool GetThreadFriendlyMemAlloc() const; + /// @copydoc GetThreadFriendlyMemAlloc VTKM_CONT void SetThreadFriendlyMemAlloc(bool state); - /// \brief Copies the state from the given device. + /// @brief Copies the state from the given device. /// /// This is a convenient way to allow the `RuntimeDeviceTracker` on one thread /// copy the behavior from another thread. /// VTKM_CONT void CopyStateFrom(const vtkm::cont::RuntimeDeviceTracker& tracker); - ///@{ - /// \brief Set/Clear the abort checker functor. + /// @brief Set/Clear the abort checker functor. /// - /// If set the abort checker functor is called by \c TryExecute before scheduling - /// a task on a device from the associated the thread. If the functor returns - /// \e true, an exception is thrown. + /// If set the abort checker functor is called by `vtkm::cont::TryExecute()` + /// before scheduling a task on a device from the associated the thread. If + /// the functor returns `true`, an exception is thrown. VTKM_CONT void SetAbortChecker(const std::function& func); + /// @copydoc SetAbortChecker VTKM_CONT void ClearAbortChecker(); - ///@} VTKM_CONT bool CheckForAbortRequest() const; + /// @brief Produce a human-readable report on the state of the runtime device tracker. VTKM_CONT void PrintSummary(std::ostream& out) const; private: - friend struct ScopedRuntimeDeviceTracker; + friend class ScopedRuntimeDeviceTracker; detail::RuntimeDeviceTrackerInternals* Internals; @@ -175,20 +176,35 @@ VTKM_CONT_EXPORT VTKM_CONT vtkm::cont::RuntimeDeviceTracker& GetRuntimeDeviceTracker(); +/// @brief Identifier used to specify whether to enable or disable a particular device. enum struct RuntimeDeviceTrackerMode { + // Documentation is below (for better layout in generated documents). Force, Enable, Disable }; -///---------------------------------------------------------------------------- +/// @var RuntimeDeviceTrackerMode Force +/// @brief Replaces the current list of devices to try with the device specified. +/// +/// This has the effect of forcing VTK-m to use the provided device. +/// This is the default behavior for `vtkm::cont::ScopedRuntimeDeviceTracker`. + +/// @var RuntimeDeviceTrackerMode Enable +/// @brief Adds the provided device adapter to the list of devices to try. + +/// @var RuntimeDeviceTrackerMode Disable +/// @brief Removes the provided device adapter from the list of devices to try. + +//---------------------------------------------------------------------------- /// A class to create a scoped runtime device tracker object. This object captures the state /// of the per-thread device tracker and will revert any changes applied /// during its lifetime on destruction. /// -struct VTKM_CONT_EXPORT ScopedRuntimeDeviceTracker : public vtkm::cont::RuntimeDeviceTracker +class VTKM_CONT_EXPORT ScopedRuntimeDeviceTracker : public vtkm::cont::RuntimeDeviceTracker { +public: /// Construct a ScopedRuntimeDeviceTracker associated with the thread, /// associated with the provided tracker (defaults to current thread's tracker). /// diff --git a/vtkm/cont/Timer.h b/vtkm/cont/Timer.h index 8379e044a..fc0a18ac6 100644 --- a/vtkm/cont/Timer.h +++ b/vtkm/cont/Timer.h @@ -50,30 +50,54 @@ public: VTKM_CONT ~Timer(); - /// Resets the timer. + /// @brief Restores the initial state of the :class:`vtkm::cont::Timer`. + /// + /// All previous recorded time is erased. `Reset()` optionally takes a device + /// adapter tag or id that specifies on which device to time and synchronize. VTKM_CONT void Reset(); /// Resets the timer and changes the device to time on. VTKM_CONT void Reset(vtkm::cont::DeviceAdapterId device); + /// @brief Causes the `Timer` to begin timing. + /// + /// The elapsed time will record an interval beginning when this method is called. VTKM_CONT void Start(); + /// @brief Causes the `Timer()` to finish timing. + /// + /// The elapsed time will record an interval ending when this method is called. + /// It is invalid to stop the timer if `Started()` is not true. VTKM_CONT void Stop(); + /// @brief Returns true if `Start()` has been called. + /// + /// It is invalid to try to get the elapsed time if `Started()` is not true. VTKM_CONT bool Started() const; + /// @brief Returns true if `Timer::Stop()` has been called. + /// + /// If `Stopped()` is true, then the elapsed time will no longer increase. + /// If `Stopped()` is false and `Started()` is true, then the timer is still running. VTKM_CONT bool Stopped() const; /// Used to check if Timer has finished the synchronization to get the result from the device. VTKM_CONT bool Ready() const; - /// Get the elapsed time measured by the given device adapter. If no device is - /// specified, the max time of all device measurements will be returned. + /// @brief Returns the amount of time that has elapsed between calling `Start()` and `Stop()`. + /// + /// If `Stop()` was not called, then the amount of time between calling `Start()` and + /// `GetElapsedTime()` is returned. `GetElapsedTime()` can optionally take a device + /// adapter tag or id to specify for which device to return the elapsed time. Returns the + /// device for which this timer is synchronized. If the device adapter has the same + /// id as `vtkm::cont::DeviceAdapterTagAny`, then the timer will synchronize all devices. VTKM_CONT vtkm::Float64 GetElapsedTime() const; - /// Returns the device for which this timer is synchronized. If the device adapter has the same - /// id as `DeviceAdapterTagAny`, then the timer will synchronize all devices. + /// @brief Returns the id of the device adapter for which this timer is synchronized. + /// + /// If the device adapter has the same id as `vtkm::cont::DeviceAdapterTagAny` + /// (the default), then the timer will synchronize on all devices. VTKM_CONT vtkm::cont::DeviceAdapterId GetDevice() const { return this->Device; } /// Synchronize the device(s) that this timer is monitoring without starting or stopping the diff --git a/vtkm/cont/cuda/internal/DeviceAdapterTagCuda.h b/vtkm/cont/cuda/internal/DeviceAdapterTagCuda.h index 48d5f146e..88bd178e4 100644 --- a/vtkm/cont/cuda/internal/DeviceAdapterTagCuda.h +++ b/vtkm/cont/cuda/internal/DeviceAdapterTagCuda.h @@ -12,6 +12,13 @@ #include +/// @struct vtkm::cont::DeviceAdapterTagCuda +/// @brief Tag for a device adapter that uses a CUDA capable GPU device. +/// +/// For this device to work, VTK-m must be configured to use CUDA and the code must +/// be compiled by the CUDA `nvcc` compiler. This tag is defined in +/// `vtkm/cont/cuda/DeviceAdapterCuda.h`. + // We always create the cuda tag when included, but we only mark it as a valid tag when // VTKM_ENABLE_CUDA is true. This is for easier development of multi-backend systems. // diff --git a/vtkm/cont/kokkos/internal/DeviceAdapterTagKokkos.h b/vtkm/cont/kokkos/internal/DeviceAdapterTagKokkos.h index 8ed4240ea..aceebcb6a 100644 --- a/vtkm/cont/kokkos/internal/DeviceAdapterTagKokkos.h +++ b/vtkm/cont/kokkos/internal/DeviceAdapterTagKokkos.h @@ -12,6 +12,14 @@ #include +/// @struct vtkm::cont::DeviceAdapterTagKokkos +/// @brief Tag for a device adapter that uses the Kokkos library to run algorithms in parallel. +/// +/// For this device to work, VTK-m must be configured to use Kokkos and the executable +/// must be linked to the Kokkos libraries. VTK-m will use the default execution space +/// of the provided kokkos library build. This tag is defined in +/// `vtkm/cont/kokkos/DeviceAdapterKokkos.h`. + //We always create the kokkos tag when included, but we only mark it as //a valid tag when VTKM_ENABLE_KOKKOS is true. This is for easier development //of multi-backend systems diff --git a/vtkm/cont/openmp/internal/DeviceAdapterTagOpenMP.h b/vtkm/cont/openmp/internal/DeviceAdapterTagOpenMP.h index f1bfb4a54..eb0ce0612 100644 --- a/vtkm/cont/openmp/internal/DeviceAdapterTagOpenMP.h +++ b/vtkm/cont/openmp/internal/DeviceAdapterTagOpenMP.h @@ -13,6 +13,14 @@ #include +/// @struct vtkm::cont::DeviceAdapterTagOpenMP +/// @brief Tag for a device adapter that uses OpenMP compiler extensions to +/// run algorithms on multiple threads. +/// +/// For this device to work, VTK-m must be configured to use OpenMP and the code +/// must be compiled with a compiler that supports OpenMP pragmas. This tag is +/// defined in `vtkm/cont/openmp/DeviceAdapterOpenMP.h`. + #ifdef VTKM_ENABLE_OPENMP VTKM_VALID_DEVICE_ADAPTER(OpenMP, VTKM_DEVICE_ADAPTER_OPENMP) #else diff --git a/vtkm/cont/serial/internal/DeviceAdapterTagSerial.h b/vtkm/cont/serial/internal/DeviceAdapterTagSerial.h index 80d87be47..9bb594d60 100644 --- a/vtkm/cont/serial/internal/DeviceAdapterTagSerial.h +++ b/vtkm/cont/serial/internal/DeviceAdapterTagSerial.h @@ -12,6 +12,13 @@ #include +/// @struct vtkm::cont::DeviceAdapterTagSerial +/// @brief Tag for a device adapter that performs all computation on the +/// same single thread as the control environment. +/// +/// This device is useful for debugging. This device is always available. This tag is +/// defined in `vtkm/cont/DeviceAdapterSerial.h`. + VTKM_VALID_DEVICE_ADAPTER(Serial, VTKM_DEVICE_ADAPTER_SERIAL); #endif //vtk_m_cont_serial_internal_DeviceAdapterTagSerial_h diff --git a/vtkm/cont/tbb/internal/DeviceAdapterTagTBB.h b/vtkm/cont/tbb/internal/DeviceAdapterTagTBB.h index 198b7f437..312eb4c95 100644 --- a/vtkm/cont/tbb/internal/DeviceAdapterTagTBB.h +++ b/vtkm/cont/tbb/internal/DeviceAdapterTagTBB.h @@ -12,6 +12,14 @@ #include +/// @struct vtkm::cont::DeviceAdapterTagTBB +/// @brief Tag for a device adapter that uses the Intel Threading Building Blocks +/// library to run algorithms on multiple threads. +/// +/// For this device to work, VTK-m must be configured to use TBB and the executable +/// must be linked to the TBB library. This tag is defined in +/// `vtkm/cont/tbb/DeviceAdapterTBB.h`. + //We always create the tbb tag when included, but we only mark it as //a valid tag when VTKM_ENABLE_TBB is true. This is for easier development //of multi-backend systems diff --git a/vtkm/filter/Filter.h b/vtkm/filter/Filter.h index 471c13500..c247a9f9f 100644 --- a/vtkm/filter/Filter.h +++ b/vtkm/filter/Filter.h @@ -42,7 +42,7 @@ namespace filter /// /// // select fields to map to the output, if different from default which is to map all input /// // fields. -/// contour.SetFieldToPass({"var1", "var2"}); +/// contour.SetFieldsToPass({"var1", "var2"}); /// /// // execute the filter on vtkm::cont::DataSet. /// vtkm::cont::DataSet dsInput = ... @@ -253,7 +253,6 @@ public: } } - ///@{ /// \brief Specify which fields get passed from input to output. /// /// After a filter successfully executes and returns a new data set, fields are mapped from @@ -264,42 +263,47 @@ public: /// By default, all fields are passed during execution. /// VTKM_CONT void SetFieldsToPass(const vtkm::filter::FieldSelection& fieldsToPass); + /// @copydoc SetFieldsToPass VTKM_CONT void SetFieldsToPass(vtkm::filter::FieldSelection&& fieldsToPass); VTKM_DEPRECATED(2.0) VTKM_CONT void SetFieldsToPass(const vtkm::filter::FieldSelection& fieldsToPass, vtkm::filter::FieldSelection::Mode mode); + /// @copydoc SetFieldsToPass VTKM_CONT void SetFieldsToPass( std::initializer_list fields, vtkm::filter::FieldSelection::Mode mode = vtkm::filter::FieldSelection::Mode::Select); + /// @copydoc SetFieldsToPass VTKM_CONT void SetFieldsToPass( std::initializer_list> fields, vtkm::filter::FieldSelection::Mode mode = vtkm::filter::FieldSelection::Mode::Select); + /// @copydoc SetFieldsToPass VTKM_CONT void SetFieldsToPass( const std::string& fieldname, vtkm::cont::Field::Association association, vtkm::filter::FieldSelection::Mode mode = vtkm::filter::FieldSelection::Mode::Select); + /// @copydoc SetFieldsToPass VTKM_CONT void SetFieldsToPass(const std::string& fieldname, vtkm::filter::FieldSelection::Mode mode) { this->SetFieldsToPass(fieldname, vtkm::cont::Field::Association::Any, mode); } + /// @copydoc SetFieldsToPass VTKM_CONT const vtkm::filter::FieldSelection& GetFieldsToPass() const { return this->FieldsToPass; } + /// @copydoc SetFieldsToPass VTKM_CONT vtkm::filter::FieldSelection& GetFieldsToPass() { return this->FieldsToPass; } - ///@} - ///@{ /// \brief Specify whether to always pass coordinate systems. /// - /// `CoordinateSystem`s in a `DataSet` are really just point fields marked as being a + /// `vtkm::cont::CoordinateSystem`s in a `DataSet` are really just point fields marked as being a /// coordinate system. Thus, a coordinate system is passed if and only if the associated /// field is passed. /// @@ -308,22 +312,18 @@ public: /// to `false`, then coordinate systems will only be passed if it is marked so by /// `FieldsToPass`. VTKM_CONT void SetPassCoordinateSystems(bool flag) { this->PassCoordinateSystems = flag; } + /// @copydoc SetPassCoordinateSystems VTKM_CONT bool GetPassCoordinateSystems() const { return this->PassCoordinateSystems; } - ///@} - ///@{ /// Executes the filter on the input and produces a result dataset. /// - /// On success, this the dataset produced. On error, vtkm::cont::ErrorExecution will be thrown. + /// On success, this the dataset produced. On error, `vtkm::cont::ErrorExecution` will be thrown. VTKM_CONT vtkm::cont::DataSet Execute(const vtkm::cont::DataSet& input); - ///@} - ///@{ /// Executes the filter on the input PartitionedDataSet and produces a result PartitionedDataSet. /// - /// On success, this the dataset produced. On error, vtkm::cont::ErrorExecution will be thrown. + /// On success, this the dataset produced. On error, `vtkm::cont::ErrorExecution` will be thrown. VTKM_CONT vtkm::cont::PartitionedDataSet Execute(const vtkm::cont::PartitionedDataSet& input); - ///@} // FIXME: Is this actually materialize? Are there different kinds of Invoker? /// Specify the vtkm::cont::Invoker to be used to execute worklets by @@ -416,7 +416,6 @@ protected: return outDataSet; } - ///@{ /// \brief Create the output data set for `DoExecute`. /// /// This form of `CreateResult` will create an output data set with the given `CellSet` @@ -456,6 +455,27 @@ protected: return outDataSet; } + /// \brief Create the output data set for `DoExecute`. + /// + /// This form of `CreateResult` will create an output data set with the given `CellSet` + /// and `CoordinateSystem`. You must also provide a field mapper function, which is a + /// function that takes the output `DataSet` being created and a `Field` from the input + /// and then applies any necessary transformations to the field array and adds it to + /// the `DataSet`. + /// + /// \param[in] inDataSet The input data set being modified (usually the one passed + /// into `DoExecute`). The returned `DataSet` is filled with fields of `inDataSet` + /// (as selected by the `FieldsToPass` state of the filter). + /// \param[in] resultCellSet The `CellSet` of the output will be set to this. + /// \param[in] coordsName The name of the coordinate system to be added to the output. + /// \param[in] coordsData The array containing the coordinates of the points. + /// \param[in] fieldMapper A function or functor that takes a `DataSet` as its first + /// argument and a `Field` as its second argument. The `DataSet` is the data being + /// created and will eventually be returned by `CreateResult`. The `Field` comes from + /// `inDataSet`. The function should map the `Field` to match `resultCellSet` and then + /// add the resulting field to the `DataSet`. If the mapping is not possible, then + /// the function should do nothing. + /// template VTKM_CONT vtkm::cont::DataSet CreateResultCoordinateSystem( const vtkm::cont::DataSet& inDataSet, @@ -470,7 +490,6 @@ protected: vtkm::cont::CoordinateSystem{ coordsName, coordsData }, fieldMapper); } - ///@} VTKM_CONT virtual vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& inData) = 0; VTKM_CONT virtual vtkm::cont::PartitionedDataSet DoExecutePartitions( diff --git a/vtkm/filter/FilterField.h b/vtkm/filter/FilterField.h index aa89f5943..62e56ae86 100644 --- a/vtkm/filter/FilterField.h +++ b/vtkm/filter/FilterField.h @@ -20,20 +20,21 @@ namespace vtkm namespace filter { +/// @brief A base class for filters that input and output fields. class VTKM_FILTER_CORE_EXPORT FilterField : public vtkm::filter::Filter { public: FilterField() { this->SetActiveCoordinateSystem(0); } + /// Specifies the name of the output field generated. VTKM_CONT void SetOutputFieldName(const std::string& name) { this->OutputFieldName = name; } + /// Specifies the name of the output field generated. VTKM_CONT const std::string& GetOutputFieldName() const { return this->OutputFieldName; } - ///@{ - /// Choose the field to operate on. Note, if - /// `this->UseCoordinateSystemAsField` is true, then the active field is not used. + /// Choose the field to operate on. VTKM_CONT void SetActiveField( const std::string& name, @@ -42,6 +43,7 @@ public: this->SetActiveField(0, name, association); } + /// Choose the field to operate on. void SetActiveField( vtkm::IdComponent index, const std::string& name, @@ -53,6 +55,7 @@ public: this->ActiveFieldAssociation[index_st] = association; } + /// Choose the field to operate on. VTKM_CONT const std::string& GetActiveFieldName(vtkm::IdComponent index = 0) const { VTKM_ASSERT((index >= 0) && @@ -60,23 +63,25 @@ public: return this->ActiveFieldNames[index]; } + /// Choose the field to operate on. VTKM_CONT vtkm::cont::Field::Association GetActiveFieldAssociation( vtkm::IdComponent index = 0) const { return this->ActiveFieldAssociation[index]; } - ///@} - ///@{ - /// Select the coordinate system coord_idx to make active to use when processing the input - /// DataSet. This is used primarily by the Filter to select the coordinate system - /// to use as a field when \c UseCoordinateSystemAsField is true. + /// Select the coordinate system index to make active to use when processing the input + /// `vtkm::cont::DataSet`. This is used primarily by the Filter to select the + /// coordinate system to use as a field when `UseCoordinateSystemAsField` is true. VTKM_CONT void SetActiveCoordinateSystem(vtkm::Id coord_idx) { this->SetActiveCoordinateSystem(0, coord_idx); } + /// Select the coordinate system index to make active to use when processing the input + /// `vtkm::cont::DataSet`. This is used primarily by the Filter to select the + /// coordinate system to use as a field when `UseCoordinateSystemAsField` is true. VTKM_CONT void SetActiveCoordinateSystem(vtkm::IdComponent index, vtkm::Id coord_idx) { @@ -85,26 +90,23 @@ public: this->ActiveCoordinateSystemIndices[index_st] = coord_idx; } + /// Select the coordinate system index to make active to use when processing the input + /// `vtkm::cont::DataSet`. This is used primarily by the Filter to select the + /// coordinate system to use as a field when `UseCoordinateSystemAsField` is true. VTKM_CONT - vtkm::Id GetActiveCoordinateSystemIndex() const - { - return this->GetActiveCoordinateSystemIndex(0); - } - - VTKM_CONT - vtkm::Id GetActiveCoordinateSystemIndex(vtkm::IdComponent index) const + vtkm::Id GetActiveCoordinateSystemIndex(vtkm::IdComponent index = 0) const { auto index_st = static_cast(index); return this->ActiveCoordinateSystemIndices[index_st]; } - ///@} - ///@{ - /// To simply use the active coordinate system as the field to operate on, set - /// UseCoordinateSystemAsField to true. + /// Specifies whether to use point coordinates as the input field. When true, the values + /// for the active field are ignored and the active coordinate system is used instead. VTKM_CONT void SetUseCoordinateSystemAsField(bool val) { SetUseCoordinateSystemAsField(0, val); } + /// Specifies whether to use point coordinates as the input field. When true, the values + /// for the active field are ignored and the active coordinate system is used instead. VTKM_CONT void SetUseCoordinateSystemAsField(vtkm::IdComponent index, bool val) { @@ -113,6 +115,8 @@ public: this->UseCoordinateSystemAsField[index] = val; } + /// Specifies whether to use point coordinates as the input field. When true, the values + /// for the active field are ignored and the active coordinate system is used instead. VTKM_CONT bool GetUseCoordinateSystemAsField(vtkm::IdComponent index = 0) const { @@ -120,7 +124,6 @@ public: (index < static_cast(this->ActiveFieldNames.size()))); return this->UseCoordinateSystemAsField[index]; } - ///@} /// \brief Return the number of active fields currently set. /// @@ -162,15 +165,15 @@ protected: } } - ///@{ /// \brief Convenience method to get the array from a filter's input scalar field. /// /// A field filter typically gets its input fields using the internal `GetFieldFromDataSet`. /// To use this field in a worklet, it eventually needs to be converted to an - /// `ArrayHandle`. If the input field is limited to be a scalar field, then this method - /// provides a convenient way to determine the correct array type. Like other `CastAndCall` - /// methods, it takes as input a `Field` (or `UnknownArrayHandle`) and a function/functor - /// to call with the appropriate `ArrayHandle` type. + /// `vtkm::cont::ArrayHandle`. If the input field is limited to be a scalar field, + /// then this method provides a convenient way to determine the correct array type. + /// Like other `CastAndCall` methods, it takes as input a `vtkm::cont::Field` (or + /// `vtkm::cont::UnknownArrayHandle`) and a function/functor to call with the appropriate + /// `vtkm::cont::ArrayHandle` type. /// template VTKM_CONT void CastAndCallScalarField(const vtkm::cont::UnknownArrayHandle& fieldArray, @@ -181,7 +184,7 @@ protected: .CastAndCallForTypesWithFloatFallback( std::forward(functor), std::forward(args)...); } - + /// @copydoc CastAndCallScalarField template VTKM_CONT void CastAndCallScalarField(const vtkm::cont::Field& field, Functor&& functor, @@ -190,7 +193,6 @@ protected: this->CastAndCallScalarField( field.GetData(), std::forward(functor), std::forward(args)...); } - ///@} private: @@ -202,17 +204,17 @@ private: }; protected: - ///@{ /// \brief Convenience method to get the array from a filter's input vector field. /// /// A field filter typically gets its input fields using the internal `GetFieldFromDataSet`. /// To use this field in a worklet, it eventually needs to be converted to an - /// `ArrayHandle`. If the input field is limited to be a vector field with vectors of a - /// specific size, then this method provides a convenient way to determine the correct array - /// type. Like other `CastAndCall` methods, it takes as input a `Field` (or - /// `UnknownArrayHandle`) and a function/functor to call with the appropriate `ArrayHandle` - /// type. You also have to provide the vector size as the first template argument. - /// For example `CastAndCallVecField<3>(field, functor);`. + /// `vtkm::cont::ArrayHandle`. If the input field is limited to be a vector field with + /// vectors of a specific size, then this method provides a convenient way to determine + /// the correct array type. Like other `CastAndCall` methods, it takes as input a + /// `vtkm::cont::Field` (or `vtkm::cont::UnknownArrayHandle`) and a function/functor to + /// call with the appropriate `vtkm::cont::ArrayHandle` type. You also have to provide the + /// vector size as the first template argument. For example + /// `CastAndCallVecField<3>(field, functor);`. /// template VTKM_CONT void CastAndCallVecField(const vtkm::cont::UnknownArrayHandle& fieldArray, @@ -224,7 +226,7 @@ protected: fieldArray.CastAndCallForTypesWithFloatFallback( std::forward(functor), std::forward(args)...); } - + /// @copydoc CastAndCallVecField template VTKM_CONT void CastAndCallVecField(const vtkm::cont::Field& field, Functor&& functor, @@ -233,19 +235,17 @@ protected: this->CastAndCallVecField( field.GetData(), std::forward(functor), std::forward(args)...); } - ///@} - ///@{ /// This method is like `CastAndCallVecField` except that it can be used for a /// field of unknown vector size (or scalars). This method will call the given - /// functor with an `ArrayHandleRecombineVec`. + /// functor with an `vtkm::cont::ArrayHandleRecombineVec`. /// - /// Note that there are limitations with using `ArrayHandleRecombineVec` within a - /// worklet. Because the size of the vectors are not known at compile time, you - /// cannot just create an intermediate `Vec` of the correct size. Typically, you - /// must allocate the output array (for example, with `ArrayHandleRuntimeVec`), and - /// the worklet must iterate over the components and store them in the prealocated - /// output. + /// Note that there are limitations with using `vtkm::cont::ArrayHandleRecombineVec` + /// within a worklet. Because the size of the vectors are not known at compile time, + /// you cannot just create an intermediate `vtkm::Vec` of the correct size. Typically, + /// you must allocate the output array (for example, with + /// `vtkm::cont::ArrayHandleRuntimeVec`), and the worklet must iterate over the + /// components and store them in the prealocated output. /// template VTKM_CONT void CastAndCallVariableVecField(const vtkm::cont::UnknownArrayHandle& fieldArray, @@ -269,7 +269,7 @@ protected: std::forward(args)...); } } - + /// @copydoc CastAndCallVariableVecField template VTKM_CONT void CastAndCallVariableVecField(const vtkm::cont::Field& field, Functor&& functor, @@ -278,7 +278,6 @@ protected: this->CastAndCallVariableVecField( field.GetData(), std::forward(functor), std::forward(args)...); } - ///@} /// \brief Create the output data set for `DoExecute` /// diff --git a/vtkm/filter/clean_grid/CleanGrid.h b/vtkm/filter/clean_grid/CleanGrid.h index 1349b4dbf..2f19a2b62 100644 --- a/vtkm/filter/clean_grid/CleanGrid.h +++ b/vtkm/filter/clean_grid/CleanGrid.h @@ -23,27 +23,30 @@ namespace clean_grid { struct SharedStates; -/// \brief Clean a mesh to an unstructured grid +/// \brief Clean a mesh to an unstructured grid. /// -/// This filter takes a data set and essentially copies it into a new data set. +/// This filter converts the cells of its input to an explicit representation +/// and potentially removes redundant or unused data. /// The newly constructed data set will have the same cells as the input and -/// the topology will be stored in a \c CellSetExplicit<>. The filter will also +/// the topology will be stored in a `vtkm::cont::CellSetExplicit<>`. The filter will also /// optionally remove all unused points. /// -/// Note that the result of \c CleanGrid is not necessarily smaller than the -/// input. For example, "cleaning" a data set with a \c CellSetStructured +/// Note that the result of `CleanGrid` is not necessarily smaller than the +/// input. For example, "cleaning" a data set with a `vtkm::cont::CellSetStructured` /// topology will actually result in a much larger data set. /// -/// \todo Add a feature to merge points that are coincident or within a -/// tolerance. +/// `CleanGrid` can optionally merge close points. The closeness of points is determined +/// by the coordinate system. If there are multiple coordinate systems, the desired +/// coordinate system can be selected with the `SetActiveCoordinateSystem()` method. /// class VTKM_FILTER_CLEAN_GRID_EXPORT CleanGrid : public vtkm::filter::FilterField { public: - /// When the CompactPointFields flag is true, the filter will identify any + /// When the CompactPointFields flag is true, the filter will identify and remove any /// points that are not used by the topology. This is on by default. /// VTKM_CONT bool GetCompactPointFields() const { return this->CompactPointFields; } + /// @copydoc GetCompactPointFields VTKM_CONT void SetCompactPointFields(bool flag) { this->CompactPointFields = flag; } /// When the MergePoints flag is true, the filter will identify any coincident @@ -51,13 +54,18 @@ public: /// coincident is set with the tolerance flags. This is on by default. /// VTKM_CONT bool GetMergePoints() const { return this->MergePoints; } + /// @copydoc GetMergePoints VTKM_CONT void SetMergePoints(bool flag) { this->MergePoints = flag; } /// Defines the tolerance used when determining whether two points are considered - /// coincident. If the ToleranceIsAbsolute flag is false (the default), then this - /// tolerance is scaled by the diagonal of the points. + /// coincident. Because floating point parameters have limited precision, point + /// coordinates that are essentially the same might not be bit-wise exactly the same. + /// Thus, the `CleanGrid` filter has the ability to find and merge points that are + /// close but perhaps not exact. If the ToleranceIsAbsolute flag is false (the default), + /// then this tolerance is scaled by the diagonal of the points. /// VTKM_CONT vtkm::Float64 GetTolerance() const { return this->Tolerance; } + /// @copydoc GetTolerance VTKM_CONT void SetTolerance(vtkm::Float64 tolerance) { this->Tolerance = tolerance; } /// When ToleranceIsAbsolute is false (the default) then the tolerance is scaled @@ -65,12 +73,16 @@ public: /// taken as the actual distance to use. /// VTKM_CONT bool GetToleranceIsAbsolute() const { return this->ToleranceIsAbsolute; } + /// @copydoc GetToleranceIsAbsolute VTKM_CONT void SetToleranceIsAbsolute(bool flag) { this->ToleranceIsAbsolute = flag; } - /// Determine whether a cell is degenerate (that is, has repeated points that drops - /// its dimensionalit) and removes them. This is on by default. + /// When RemoveDegenerateCells is true (the default), then `CleanGrid` will look + /// for repeated points in cells and, if the repeated points cause the cell to drop + /// dimensionality, the cell is removed. This is particularly useful when point merging + /// is on as this operation can create degenerate cells. /// VTKM_CONT bool GetRemoveDegenerateCells() const { return this->RemoveDegenerateCells; } + /// @copydoc GetRemoveDegenerateCells VTKM_CONT void SetRemoveDegenerateCells(bool flag) { this->RemoveDegenerateCells = flag; } /// When FastMerge is true (the default), some corners are cut when computing @@ -78,6 +90,7 @@ public: /// be strictly followed. /// VTKM_CONT bool GetFastMerge() const { return this->FastMerge; } + /// @copydoc GetFastMerge VTKM_CONT void SetFastMerge(bool flag) { this->FastMerge = flag; } private: diff --git a/vtkm/filter/connected_components/CellSetConnectivity.h b/vtkm/filter/connected_components/CellSetConnectivity.h index 44d6e4e2d..0cdc4f38e 100644 --- a/vtkm/filter/connected_components/CellSetConnectivity.h +++ b/vtkm/filter/connected_components/CellSetConnectivity.h @@ -21,13 +21,14 @@ namespace filter namespace connected_components { -/// \brief Finds groups of cells that are connected together through their topology. +/// \brief Finds and labels groups of cells that are connected together through their topology. /// -/// Finds and labels groups of cells that are connected together through their topology. -/// Two cells are considered connected if they share an edge. CellSetConnectivity identifies some +/// Two cells are considered connected if they share an edge. `CellSetConnectivity` identifies some /// number of components and assigns each component a unique integer. -/// The result of the filter is a cell field of type vtkm::Id with the default name of 'component'. -/// Each entry in the cell field will be a number that identifies to which component the cell belongs. +/// +/// The result of the filter is a cell field of type `vtkm::Id` with the default name of +/// "component" (which can be changed with the `SetOutputFieldName` method). Each entry in +/// the cell field will be a number that identifies to which component the cell belongs. class VTKM_FILTER_CONNECTED_COMPONENTS_EXPORT CellSetConnectivity : public vtkm::filter::FilterField { public: diff --git a/vtkm/filter/connected_components/ImageConnectivity.h b/vtkm/filter/connected_components/ImageConnectivity.h index ba2d0d6cf..be6ca8d39 100644 --- a/vtkm/filter/connected_components/ImageConnectivity.h +++ b/vtkm/filter/connected_components/ImageConnectivity.h @@ -14,16 +14,18 @@ #include #include -/// \brief Groups connected points that have the same field value -/// +/// \brief Groups connected points that have the same field value. /// /// The ImageConnectivity filter finds groups of points that have the same field value and are /// connected together through their topology. Any point is considered to be connected to its Moore neighborhood: -/// 8 neighboring points for 2D and 27 neighboring points for 3D. As the name implies, ImageConnectivity only +/// 8 neighboring points for 2D and 27 neighboring points for 3D. As the name implies, `ImageConnectivity` only /// works on data with a structured cell set. You will get an error if you use any other type of cell set. +/// /// The active field passed to the filter must be associated with the points. -/// The result of the filter is a point field of type vtkm::Id. Each entry in the point field will be a number that -/// identifies to which region it belongs. By default, this output point field is named “component”. +/// +/// The result of the filter is a point field of type `vtkm::Id`. Each entry in the point field will be a number that +/// identifies to which region it belongs. By default, this output point field is named "component" +/// (which can be changed with the `SetOutputFieldName` method). namespace vtkm { namespace filter diff --git a/vtkm/filter/contour/AbstractContour.h b/vtkm/filter/contour/AbstractContour.h index fad11af86..871c57e79 100644 --- a/vtkm/filter/contour/AbstractContour.h +++ b/vtkm/filter/contour/AbstractContour.h @@ -25,7 +25,7 @@ namespace contour /// \brief Contour filter interface /// /// Provides common configuration & execution methods for contour filters -/// Only the method \c DoExecute executing the contour algorithm needs to be implemented +/// Only the method `DoExecute` executing the contour algorithm needs to be implemented class VTKM_FILTER_CONTOUR_EXPORT AbstractContour : public vtkm::filter::FilterField { public: @@ -39,8 +39,15 @@ public: vtkm::Id GetNumberOfIsoValues() const { return static_cast(this->IsoValues.size()); } + /// @brief Set a field value on which to extract a contour. + /// + /// This form of the method is usually used when only one contour is being extracted. void SetIsoValue(vtkm::Float64 v) { this->SetIsoValue(0, v); } + /// @brief Set a field value on which to extract a contour. + /// + /// This form is used to specify multiple contours. The method is called + /// multiple times with different @a index parameters. void SetIsoValue(vtkm::Id index, vtkm::Float64 v) { std::size_t i = static_cast(index); @@ -51,44 +58,91 @@ public: this->IsoValues[i] = v; } + /// @brief Set multiple iso values at once. + /// + /// The iso values can be specified as either a `std::vector` or an initializer list. + /// So, both + /// + /// @code{.cpp} + /// std::vector isovalues = { 0.2, 0.5, 0.7 }; + /// contour.SetIsoValues(isovalues); + /// @endcode + /// + /// and + /// + /// @code{.cpp} + /// contour.SetIsoValues({ 0.2, 0.5, 0.7 }); + /// @endcode + /// + /// work. void SetIsoValues(const std::vector& values) { this->IsoValues = values; } - vtkm::Float64 GetIsoValue(vtkm::Id index) const + /// @brief Return a value used to contour the mesh. + vtkm::Float64 GetIsoValue(vtkm::Id index = 0) const { return this->IsoValues[static_cast(index)]; } - /// Set/Get whether normals should be generated. Off by default. + /// @brief Set whether normals should be generated. + /// + /// Normals are used in shading calculations during rendering and can make the + /// surface appear more smooth. + /// + /// Off by default. VTKM_CONT - void SetGenerateNormals(bool on) { this->GenerateNormals = on; } + void SetGenerateNormals(bool flag) { this->GenerateNormals = flag; } + /// Get whether normals should be generated. VTKM_CONT bool GetGenerateNormals() const { return this->GenerateNormals; } - /// Set/Get whether to append the ids of the intersected edges to the vertices of the isosurface triangles. Off by default. + /// Set whether to append the ids of the intersected edges to the vertices of the isosurface + /// triangles. Off by default. VTKM_CONT - void SetAddInterpolationEdgeIds(bool on) { this->AddInterpolationEdgeIds = on; } + void SetAddInterpolationEdgeIds(bool flag) { this->AddInterpolationEdgeIds = flag; } + /// Get whether to append the ids of the intersected edges to the vertices of the isosurface + /// triangles. VTKM_CONT bool GetAddInterpolationEdgeIds() const { return this->AddInterpolationEdgeIds; } - /// Set/Get whether the fast path should be used for normals computation. Off by default. + /// @brief Set whether the fast path should be used for normals computation. + /// + /// When this flag is off (the default), the generated normals are based on + /// the gradient of the field being contoured and can be quite expensive to compute. + /// When the flag is on, a faster method that computes the normals based on the faces + /// of the isosurface mesh is used, but the normals do not look as good as the + /// gradient based normals. + /// + /// This flag has no effect if `SetGenerateNormals` is false. VTKM_CONT - void SetComputeFastNormals(bool on) { this->ComputeFastNormals = on; } + void SetComputeFastNormals(bool flag) { this->ComputeFastNormals = flag; } + /// Get whether the fast path should be used for normals computation. VTKM_CONT bool GetComputeFastNormals() const { return this->ComputeFastNormals; } + /// Set the name of the field for the generated normals. VTKM_CONT void SetNormalArrayName(const std::string& name) { this->NormalArrayName = name; } + /// Get the name of the field for the generated normals. VTKM_CONT const std::string& GetNormalArrayName() const { return this->NormalArrayName; } - /// Set/Get whether the points generated should be unique for every triangle + /// Set whether the points generated should be unique for every triangle /// or will duplicate points be merged together. Duplicate points are identified /// by the unique edge it was generated from. /// + /// Because the contour filter (like all filters in VTK-m) runs in parallel, parallel + /// threads can (and often do) create duplicate versions of points. When this flag is + /// set to true, a secondary operation will find all duplicated points and combine + /// them together. If false, points will be duplicated. In addition to requiring more + /// storage, duplicated points mean that triangles next to each other will not be + /// considered adjecent to subsequent filters. + /// VTKM_CONT void SetMergeDuplicatePoints(bool on) { this->MergeDuplicatedPoints = on; } + /// Get whether the points generated should be unique for every triangle + /// or will duplicate points be merged together. VTKM_CONT bool GetMergeDuplicatePoints() { return this->MergeDuplicatedPoints; } diff --git a/vtkm/filter/contour/ClipWithField.h b/vtkm/filter/contour/ClipWithField.h index ff11a3d0e..431d5ca1c 100644 --- a/vtkm/filter/contour/ClipWithField.h +++ b/vtkm/filter/contour/ClipWithField.h @@ -25,18 +25,30 @@ namespace contour /// Clip a dataset using a given field value. All points that are less than that /// value are considered outside, and will be discarded. All points that are greater /// are kept. -/// The resulting geometry will not be water tight. +/// +/// To select the scalar field, use the `SetActiveField()` and related methods. +/// class VTKM_FILTER_CONTOUR_EXPORT ClipWithField : public vtkm::filter::FilterField { public: - VTKM_CONT - void SetClipValue(vtkm::Float64 value) { this->ClipValue = value; } + /// @brief Specifies the field value for the clip operation. + /// + /// Regions where the active field is less than this value are clipped away + /// from each input cell. + VTKM_CONT void SetClipValue(vtkm::Float64 value) { this->ClipValue = value; } - VTKM_CONT - void SetInvertClip(bool invert) { this->Invert = invert; } + /// @brief Specifies if the result for the clip filter should be inverted. + /// + /// If set to false (the default), regions where the active field is less than + /// the specified clip value are removed. If set to true, regions where the active + /// field is more than the specified clip value are removed. + VTKM_CONT void SetInvertClip(bool invert) { this->Invert = invert; } - VTKM_CONT - vtkm::Float64 GetClipValue() const { return this->ClipValue; } + /// @brief Specifies the field value for the clip operation. + VTKM_CONT vtkm::Float64 GetClipValue() const { return this->ClipValue; } + + /// @brief Specifies if the result for the clip filter should be inverted. + VTKM_CONT bool GetInvertClip() const { return this->Invert; } private: vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override; diff --git a/vtkm/filter/contour/ClipWithImplicitFunction.h b/vtkm/filter/contour/ClipWithImplicitFunction.h index e469c04c8..ccc93e5e4 100644 --- a/vtkm/filter/contour/ClipWithImplicitFunction.h +++ b/vtkm/filter/contour/ClipWithImplicitFunction.h @@ -23,19 +23,32 @@ namespace contour { /// \brief Clip a dataset using an implicit function /// -/// Clip a dataset using a given implicit function value, such as vtkm::Sphere -/// or vtkm::Frustum. -/// The resulting geometry will not be water tight. +/// Clip a dataset using a given implicit function value, such as `vtkm::Sphere` +/// or `vtkm::Frustum`. The implicit function uses the point coordinates as its values. +/// If there is more than one coordinate system in the input `vtkm::cont::DataSet`, +/// it can be selected with `SetActiveCoordinateSystem()`. class VTKM_FILTER_CONTOUR_EXPORT ClipWithImplicitFunction : public vtkm::filter::FilterField { public: + /// @brief Specifies the implicit function to be used to perform the clip operation. + /// + /// Only a limited number of implicit functions are supported. See + /// `vtkm::ImplicitFunctionGeneral` for information on which ones. + /// void SetImplicitFunction(const vtkm::ImplicitFunctionGeneral& func) { this->Function = func; } void SetOffset(vtkm::Float64 offset) { this->Offset = offset; } vtkm::Float64 GetOffset() const { return this->Offset; } + /// @brief Specifies whether the result of the clip filter should be inverted. + /// + /// If set to false (the default), all regions where the implicit function is negative + /// will be removed. If set to true, all regions where the implicit function is positive + /// will be removed. + /// void SetInvertClip(bool invert) { this->Invert = invert; } + /// @brief Specifies the implicit function to be used to perform the clip operation. const vtkm::ImplicitFunctionGeneral& GetImplicitFunction() const { return this->Function; } private: diff --git a/vtkm/filter/contour/Contour.h b/vtkm/filter/contour/Contour.h index 615f10cf0..1f3841e74 100644 --- a/vtkm/filter/contour/Contour.h +++ b/vtkm/filter/contour/Contour.h @@ -20,21 +20,21 @@ namespace filter { namespace contour { -/// \brief generate isosurface(s) from a Volume -/// Takes as input a volume (e.g., 3D structured point set) and generates on -/// output one or more isosurfaces. -/// Multiple contour values must be specified to generate the isosurfaces. -/// This filter automatically selects the right implmentation between Marching Cells -/// and Flying Edges algorithms depending on the type of input \c DataSet : Flying Edges -/// is only available for 3-dimensional datasets using uniform point coordinates. -/// @warning -/// This filter is currently only supports 3D volumes. +/// \brief Generate contours or isosurfaces from a region of space. +/// +/// `Contour` takes as input a mesh, often a volume, and generates on +/// output one or more surfaces where a field equals a specified value. +/// +/// This filter implements multiple algorithms for contouring, and the best algorithm +/// will be selected based on the type of the input. +/// +/// The scalar field to extract the contour from is selected with the `SetActiveField()` +/// and related methods. +/// class VTKM_FILTER_CONTOUR_EXPORT Contour : public vtkm::filter::contour::AbstractContour { public: - /// Set/Get whether the fast path should be used for normals computation for - /// structured datasets. Off by default. VTKM_DEPRECATED(2.1, "Use SetComputeFastNormals.") VTKM_CONT void SetComputeFastNormalsForStructured(bool on) { this->SetComputeFastNormals(on); } VTKM_DEPRECATED(2.1, "Use GetComputeFastNormals.") @@ -43,8 +43,6 @@ public: return this->GetComputeFastNormals(); } - /// Set/Get whether the fast path should be used for normals computation for - /// unstructured datasets. On by default. VTKM_DEPRECATED(2.1, "Use SetComputeFastNormals.") VTKM_CONT void SetComputeFastNormalsForUnstructured(bool on) { this->SetComputeFastNormals(on); } VTKM_DEPRECATED(2.1, "Use GetComputeFastNormals.") diff --git a/vtkm/filter/contour/Slice.h b/vtkm/filter/contour/Slice.h index c2bb4c18d..0ef8442f1 100644 --- a/vtkm/filter/contour/Slice.h +++ b/vtkm/filter/contour/Slice.h @@ -21,13 +21,24 @@ namespace filter { namespace contour { + +/// @brief Intersect a mesh with an implicit surface. +/// +/// This filter accepts a `vtkm::ImplicitFunction` that defines the surface to +/// slice on. A `vtkm::Plane` is a common function to use that cuts the mesh +/// along a plane. +/// class VTKM_FILTER_CONTOUR_EXPORT Slice : public vtkm::filter::contour::Contour { public: - /// Set/Get the implicit function that is used to perform the slicing. + /// @brief Set the implicit function that is used to perform the slicing. + /// + /// Only a limited number of implicit functions are supported. See + /// `vtkm::ImplicitFunctionGeneral` for information on which ones. /// VTKM_CONT void SetImplicitFunction(const vtkm::ImplicitFunctionGeneral& func) { this->Function = func; } + /// @brief Get the implicit function that us used to perform the slicing. VTKM_CONT const vtkm::ImplicitFunctionGeneral& GetImplicitFunction() const { return this->Function; } diff --git a/vtkm/filter/density_estimate/Histogram.h b/vtkm/filter/density_estimate/Histogram.h index 5f7c9193a..c4d192681 100644 --- a/vtkm/filter/density_estimate/Histogram.h +++ b/vtkm/filter/density_estimate/Histogram.h @@ -20,43 +20,58 @@ namespace filter { namespace density_estimate { -/// \brief Construct the histogram of a given Field +/// \brief Construct the histogram of a given field. /// -/// Construct a histogram with a default of 10 bins. +/// The range of the field is evenly split to a set number of bins (set by +/// `SetNumberOfBins()`). This filter then counts the number of values in the filter +/// that are in each bin. +/// +/// The result of this filter is stored in a `vtkm::cont::DataSet` with no points +/// or cells. It contains only a single field containing the histogram (bin counts). +/// The field has an association of `vtkm::cont::Field::Association::WholeDataSet`. +/// The field contains an array of `vtkm::Id` with the bin counts. By default, the +/// field is named "histogram", but that can be changed with the `SetOutputFieldName()` +/// method. +/// +/// If this filter is run on a partitioned data set, the result will be a +/// `vtkm::cont::PartitionedDataSet` containing a single +/// `vtkm::cont::DataSet` as previously described. /// class VTKM_FILTER_DENSITY_ESTIMATE_EXPORT Histogram : public vtkm::filter::FilterField { public: - //Construct a histogram with a default of 10 bins - VTKM_CONT - Histogram(); + VTKM_CONT Histogram(); - VTKM_CONT - void SetNumberOfBins(vtkm::Id count) { this->NumberOfBins = count; } + /// @brief Set the number of bins for the resulting histogram. + /// + /// By default, a histogram with 10 bins is created. + VTKM_CONT void SetNumberOfBins(vtkm::Id count) { this->NumberOfBins = count; } - VTKM_CONT - vtkm::Id GetNumberOfBins() const { return this->NumberOfBins; } + /// @brief Get the number of bins for the resulting histogram. + VTKM_CONT vtkm::Id GetNumberOfBins() const { return this->NumberOfBins; } - ///@{ - /// Get/Set the range to use to generate the histogram. If range is set to - /// empty, the field's global range (computed using `vtkm::cont::FieldRangeGlobalCompute`) - /// will be used. - VTKM_CONT - void SetRange(const vtkm::Range& range) { this->Range = range; } + /// @brief Set the range to use to generate the histogram. + /// + /// If range is set to empty, the field's global range (computed using + /// `vtkm::cont::FieldRangeGlobalCompute`) will be used. + VTKM_CONT void SetRange(const vtkm::Range& range) { this->Range = range; } - VTKM_CONT - const vtkm::Range& GetRange() const { return this->Range; } - ///@} + /// @brief Get the range used to generate the histogram. + /// + /// If the returned range is empty, then the field's global range will be used. + VTKM_CONT const vtkm::Range& GetRange() const { return this->Range; } - /// Returns the bin delta of the last computed field. - VTKM_CONT - vtkm::Float64 GetBinDelta() const { return this->BinDelta; } + /// @brief Returns the size of bin in the computed histogram. + /// + /// This value is only valid after a call to `Execute`. + VTKM_CONT vtkm::Float64 GetBinDelta() const { return this->BinDelta; } - /// Returns the range used for most recent execute. If `SetRange` is used to - /// specify and non-empty range, then this will be same as the range after - /// the `Execute` call. - VTKM_CONT - vtkm::Range GetComputedRange() const { return this->ComputedRange; } + /// @brief Returns the range used for most recent execute. + /// + /// If `SetRange` is used to specify a non-empty range, then this range will + /// be returned. Otherwise, the coputed range is returned. + /// This value is only valid after a call to `Execute`. + VTKM_CONT vtkm::Range GetComputedRange() const { return this->ComputedRange; } private: VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override; diff --git a/vtkm/filter/density_estimate/ParticleDensityBase.h b/vtkm/filter/density_estimate/ParticleDensityBase.h index dd7544d4d..154273226 100644 --- a/vtkm/filter/density_estimate/ParticleDensityBase.h +++ b/vtkm/filter/density_estimate/ParticleDensityBase.h @@ -26,41 +26,53 @@ protected: ParticleDensityBase() = default; public: - VTKM_CONT void SetComputeNumberDensity(bool yes) { this->ComputeNumberDensity = yes; } - + /// @brief Toggles between summing mass and computing instances. + /// + /// When this flag is false (the default), the active field of the input is accumulated + /// in each bin of the output. When this flag is set to true, the active field is ignored + /// and the associated particles are simply counted. + VTKM_CONT void SetComputeNumberDensity(bool flag) { this->ComputeNumberDensity = flag; } + /// @copydoc SetComputeNumberDensity VTKM_CONT bool GetComputeNumberDensity() const { return this->ComputeNumberDensity; } - VTKM_CONT void SetDivideByVolume(bool yes) { this->DivideByVolume = yes; } - + /// @brief Specifies whether the accumulated mass (or count) is divided by the volume of the cell. + /// + /// When this flag is on (the default), the computed mass will be divided by the volume of the + /// bin to give a density value. Turning off this flag provides an accumulated mass or count. + /// + VTKM_CONT void SetDivideByVolume(bool flag) { this->DivideByVolume = flag; } + /// @copydoc SetDivideByVolume VTKM_CONT bool GetDivideByVolume() const { return this->DivideByVolume; } - ///@{ /// @brief The number of bins in the grid used as regions to estimate density. /// - /// To estimate particle density, this filter defines a uniform grid in space. The - /// `Dimension` is the number of grid particles in each direction. + /// To estimate particle density, this filter defines a uniform grid in space. + /// + /// The numbers specify the number of *bins* (i.e. cells in the output mesh) in each + /// dimension, not the number of points in the output mesh. /// VTKM_CONT void SetDimension(const vtkm::Id3& dimension) { this->Dimension = dimension; } + /// @copydoc SetDimension VTKM_CONT vtkm::Id3 GetDimension() const { return this->Dimension; } - ///@} - ///@{ /// @brief The lower-left (minimum) corner of the domain of density estimation. /// VTKM_CONT void SetOrigin(const vtkm::Vec3f& origin) { this->Origin = origin; } + /// @copydoc SetOrigin VTKM_CONT vtkm::Vec3f GetOrigin() const { return this->Origin; } - ///@} - ///@{ /// @brief The spacing of the grid points used to form the grid for density estimation. /// VTKM_CONT void SetSpacing(const vtkm::Vec3f& spacing) { this->Spacing = spacing; } + /// @copydoc SetSpacing VTKM_CONT vtkm::Vec3f GetSpacing() const { return this->Spacing; } - ///@} - ///@{ /// @brief The bounds of the region where density estimation occurs. /// + /// This method can be used in place of `SetOrigin` and `SetSpacing`. It is often + /// easiest to compute the bounds of the input coordinate system (or other spatial + /// region) to use as the input. + /// /// The dimensions must be set before the bounds are set. Calling `SetDimension` /// will change the ranges of the bounds. /// @@ -80,7 +92,6 @@ public: { this->Origin[1], this->Origin[1] + (this->Spacing[1] * this->Dimension[1]) }, { this->Origin[2], this->Origin[2] + (this->Spacing[2] * this->Dimension[2]) } }; } - ///@} protected: // Note: we are using the paradoxical "const ArrayHandle&" parameter whose content can actually diff --git a/vtkm/filter/density_estimate/ParticleDensityCloudInCell.h b/vtkm/filter/density_estimate/ParticleDensityCloudInCell.h index 10e02c192..13c559b6c 100644 --- a/vtkm/filter/density_estimate/ParticleDensityCloudInCell.h +++ b/vtkm/filter/density_estimate/ParticleDensityCloudInCell.h @@ -19,22 +19,33 @@ namespace filter { namespace density_estimate { -/// \brief Estimate the density of particles using the Cloud-in-Cell method -/// This filter treats the CoordinateSystem of a DataSet as positions of particles. +/// \brief Estimate the density of particles using the Cloud-in-Cell method. +/// +/// This filter takes a collection of particles. /// The particles are infinitesimal in size with finite mass (or other scalar attributes -/// such as charge). The filter estimates density by imposing a regular grid as -/// specified in the constructor. It spreads the mass of each particle to its 8 nearest -/// neighboring grid points and summing the contribution of particles for each point -/// in the grid. -/// The mass of particles is established by setting the active field (using SetActiveField). +/// such as charge). The filter estimates density by imposing a regular grid (as +/// specified by `SetDimensions`, `SetOrigin`, and `SetSpacing`) and summing the mass +/// of particles within each cell in the grid. +/// The particle's mass is divided among the 8 nearest neighboring bins. This differs from +/// `ParticleDensityNearestGridPoint`, which just finds the nearest containing bin. +/// +/// The mass of particles is established by setting the active field (using `SetActiveField`). /// Note that the "mass" can actually be another quantity. For example, you could use /// electrical charge in place of mass to compute the charge density. -/// Once the sum of the mass is computed for each grid point, the mass is divided by the +/// Once the sum of the mass is computed for each grid cell, the mass is divided by the /// volume of the cell. Thus, the density will be computed as the units of the mass field /// per the cubic units of the coordinate system. If you just want a sum of the mass in each -/// cell, turn off the DivideByVolume feature of this filter. +/// cell, turn off the `DivideByVolume` feature of this filter. /// In addition, you can also simply count the number of particles in each cell by calling -/// SetComputeNumberDensity(true). +/// `SetComputeNumberDensity(true)`. +/// +/// This operation is helpful in the analysis of particle-based simulation where the data +/// often requires conversion or deposition of particles' attributes, such as mass, to an +/// overlaying mesh. This allows further identification of regions of interest based on the +/// spatial distribution of particles attributes, for example, high density regions could be +/// considered as clusters or halos while low density regions could be considered as bubbles +/// or cavities in the particle data. +/// class VTKM_FILTER_DENSITY_ESTIMATE_EXPORT ParticleDensityCloudInCell : public ParticleDensityBase { public: diff --git a/vtkm/filter/density_estimate/ParticleDensityNearestGridPoint.h b/vtkm/filter/density_estimate/ParticleDensityNearestGridPoint.h index c064080d9..f2c5a97e3 100644 --- a/vtkm/filter/density_estimate/ParticleDensityNearestGridPoint.h +++ b/vtkm/filter/density_estimate/ParticleDensityNearestGridPoint.h @@ -19,21 +19,36 @@ namespace filter { namespace density_estimate { -/// \brief Estimate the density of particles using the Nearest Grid Point method -/// This filter treats the CoordinateSystem of a DataSet as positions of particles. +/// \brief Estimate the density of particles using the Nearest Grid Point method. +/// +/// This filter takes a collection of particles. /// The particles are infinitesimal in size with finite mass (or other scalar attributes -/// such as charge). The filter estimates density by imposing a regular grid as -/// specified in the constructor and summing the mass of particles within each cell -/// in the grid. -/// The mass of particles is established by setting the active field (using SetActiveField). +/// such as charge). The filter estimates density by imposing a regular grid (as +/// specified by `SetDimensions`, `SetOrigin`, and `SetSpacing`) and summing the mass +/// of particles within each cell in the grid. +/// Each input particle is assigned to one bin that it falls in. +/// +/// The mass of particles is established by setting the active field (using `SetActiveField`). /// Note that the "mass" can actually be another quantity. For example, you could use /// electrical charge in place of mass to compute the charge density. /// Once the sum of the mass is computed for each grid cell, the mass is divided by the /// volume of the cell. Thus, the density will be computed as the units of the mass field /// per the cubic units of the coordinate system. If you just want a sum of the mass in each -/// cell, turn off the DivideByVolume feature of this filter. +/// cell, turn off the `DivideByVolume` feature of this filter. /// In addition, you can also simply count the number of particles in each cell by calling -/// SetComputeNumberDensity(true). +/// `SetComputeNumberDensity(true)`. +/// +/// This operation is helpful in the analysis of particle-based simulation where the data +/// often requires conversion or deposition of particles' attributes, such as mass, to an +/// overlaying mesh. This allows further identification of regions of interest based on the +/// spatial distribution of particles attributes, for example, high density regions could be +/// considered as clusters or halos while low density regions could be considered as bubbles +/// or cavities in the particle data. +/// +/// Since there is no specific `vtkm::cont::CellSet` for particles in VTK-m, this filter +/// treats the `vtkm::cont::CoordinateSystem` of the `vtkm::cont::DataSet` as the positions +/// of the particles while ignoring the details of the `vtkm::cont::CellSet`. +/// class VTKM_FILTER_DENSITY_ESTIMATE_EXPORT ParticleDensityNearestGridPoint : public ParticleDensityBase { diff --git a/vtkm/filter/density_estimate/Statistics.h b/vtkm/filter/density_estimate/Statistics.h index a10afeaac..3f317c2fb 100644 --- a/vtkm/filter/density_estimate/Statistics.h +++ b/vtkm/filter/density_estimate/Statistics.h @@ -19,9 +19,51 @@ namespace filter { namespace density_estimate { -/// \brief Calculating the statistics of input fields +/// \brief Computes descriptive statistics of an input field. /// -/// This filter calculates the statistics of input fields. +/// This filter computes the following statistics on the active field of the input. +/// +/// - `N` +/// - `Min` +/// - `Max` +/// - `Sum` +/// - `Mean` +/// - `M2` +/// - `M3` +/// - `M4` +/// - `SampleStddev` +/// - `PopulationStddev` +/// - `SampleVariance` +/// - `PopulationVariance` +/// - `Skewness` +/// - `Kurtosis` +/// +/// `M2`, `M3`, and `M4` are the second, third, and fourth moments, respectively. +/// +/// Note that this filter treats the "sample" and the "population" as the same with the +/// same mean. The difference between the two forms of variance is how they are normalized. +/// The population variance is normalized by dividing the second moment by `N`. The sample +/// variance uses Bessel's correction and divides the second moment by `N`-1 instead. +/// The standard deviation, which is just the square root of the variance, follows the +/// same difference. +/// +/// The result of this filter is stored in a `vtkm::cont::DataSet` with no points +/// or cells. It contains only fields with the same names as the list above. +/// All fields have an association of `vtkm::cont::Field::Association::WholeDataSet`. +/// +/// If `Execute` is called with a `vtkm::cont::PartitionedDataSet`, then the partitions +/// of the output will match those of the input. Additionally, the containing +/// `vtkm::cont::PartitionedDataSet` will contain the same fields associated with +/// `vtkm::cont::Field::Association::Global` that provide the overall statistics of +/// all partitions. +/// +/// If this filter is used inside of an MPI job, then each `vtkm::cont::DataSet` result +/// will be @e local to the MPI rank. If `Execute` is called with a +/// `vtkm::cont::PartitionedDataSet`, then the fields attached to the +/// `vtkm::cont::PartitionedDataSet` container will have the overall statistics across +/// all MPI ranks (in addition to all partitions). Global MPI statistics for a single +/// `vtkm::cont::DataSet` can be computed by creating a `vtkm::cont::PartitionedDataSet` +/// with that as a single partition. /// class VTKM_FILTER_DENSITY_ESTIMATE_EXPORT Statistics : public vtkm::filter::FilterField { diff --git a/vtkm/filter/entity_extraction/ExternalFaces.h b/vtkm/filter/entity_extraction/ExternalFaces.h index ad7ea9991..c7aa12b5f 100644 --- a/vtkm/filter/entity_extraction/ExternalFaces.h +++ b/vtkm/filter/entity_extraction/ExternalFaces.h @@ -24,13 +24,11 @@ namespace filter { namespace entity_extraction { -/// \brief Extract external faces of a geometry +/// @brief Extract external faces of a geometry. /// -/// ExternalFaces is a filter that extracts all external faces from a +/// `ExternalFaces` is a filter that extracts all external faces from a /// data set. An external face is defined is defined as a face/side of a cell /// that belongs only to one cell in the entire mesh. -/// @warning -/// This filter is currently only supports propagation of point properties /// class VTKM_FILTER_ENTITY_EXTRACTION_EXPORT ExternalFaces : public vtkm::filter::FilterField { @@ -42,20 +40,25 @@ public: // thread un-safe filter. bool CanThread() const override { return false; } - // When CompactPoints is set, instead of copying the points and point fields - // from the input, the filter will create new compact fields without the - // unused elements - VTKM_CONT - bool GetCompactPoints() const { return this->CompactPoints; } - VTKM_CONT - void SetCompactPoints(bool value) { this->CompactPoints = value; } + /// @brief Option to remove unused points and compact result int a smaller array. + /// + /// When CompactPoints is on, instead of copying the points and point fields + /// from the input, the filter will create new compact fields without the + /// unused elements. + /// When off (the default), unused points will remain listed in the topology, + /// but point fields and coordinate systems will be shallow-copied to the output. + VTKM_CONT bool GetCompactPoints() const { return this->CompactPoints; } + /// @copydoc GetCompactPoints + VTKM_CONT void SetCompactPoints(bool value) { this->CompactPoints = value; } - // When PassPolyData is set (the default), incoming poly data (0D, 1D, and 2D cells) - // will be passed to the output external faces data set. - VTKM_CONT - bool GetPassPolyData() const { return this->PassPolyData; } - VTKM_CONT - void SetPassPolyData(bool value); + /// @brief Specify how polygonal data (polygons, lines, and vertices) will be handled. + /// + /// When on (the default), these cells will be passed to the output. + /// When off, these cells will be removed from the output. (Because they have less than 3 + /// topological dimensions, they are not considered to have any "faces.") + VTKM_CONT bool GetPassPolyData() const { return this->PassPolyData; } + /// @copydoc GetPassPolyData + VTKM_CONT void SetPassPolyData(bool value); private: VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override; diff --git a/vtkm/filter/entity_extraction/ExtractGeometry.h b/vtkm/filter/entity_extraction/ExtractGeometry.h index 468f3c84b..03f5c71ef 100644 --- a/vtkm/filter/entity_extraction/ExtractGeometry.h +++ b/vtkm/filter/entity_extraction/ExtractGeometry.h @@ -21,7 +21,7 @@ namespace filter { namespace entity_extraction { -/// \brief Extract a subset of geometry based on an implicit function +/// @brief Extract a subset of geometry based on an implicit function /// /// Extracts from its input geometry all cells that are either /// completely inside or outside of a specified implicit function. Any type of @@ -33,41 +33,75 @@ namespace entity_extraction /// region.) An option exists to extract cells that are neither inside or /// outside (i.e., boundary). /// -/// This differs from Clip in that Clip will subdivide boundary cells into new -/// cells, while this filter will not, producing a more 'crinkly' output. +/// This differs from `vtkm::filter::contour::ClipWithImplicitFunction` in that +/// `vtkm::filter::contour::ClipWithImplicitFunction` will subdivide boundary +/// cells into new cells whereas this filter will not, producing a more "crinkly" +/// output. /// class VTKM_FILTER_ENTITY_EXTRACTION_EXPORT ExtractGeometry : public vtkm::filter::FilterField { public: - // Set the volume of interest to extract + /// @brief Specifies the implicit function to be used to perform extract geometry. + /// + /// Only a limited number of implicit functions are supported. See + /// `vtkm::ImplicitFunctionGeneral` for information on which ones. + /// + VTKM_CONT void SetImplicitFunction(const vtkm::ImplicitFunctionGeneral& func) { this->Function = func; } + VTKM_CONT const vtkm::ImplicitFunctionGeneral& GetImplicitFunction() const { return this->Function; } + /// @brief Specify the region of the implicit function to keep cells. + /// + /// Determines whether to extract the geometry that is on the inside of the implicit + /// function (where the function is less than 0) or the outside (where the function is + /// greater than 0). This flag is true by default (i.e., the interior of the implicit + /// function will be extracted). VTKM_CONT bool GetExtractInside() const { return this->ExtractInside; } + /// @copydoc GetExtractInside VTKM_CONT void SetExtractInside(bool value) { this->ExtractInside = value; } + /// @copydoc GetExtractInside VTKM_CONT void ExtractInsideOn() { this->ExtractInside = true; } + /// @copydoc GetExtractInside VTKM_CONT void ExtractInsideOff() { this->ExtractInside = false; } + /// @brief Specify whether cells on the boundary should be extracted. + /// + /// The implicit function used to extract geometry is likely to intersect some of the + /// cells of the input. If this flag is true, then any cells intersected by the implicit + /// function are extracted and included in the output. This flag is false by default. VTKM_CONT bool GetExtractBoundaryCells() const { return this->ExtractBoundaryCells; } + /// @copydoc GetExtractBoundaryCells VTKM_CONT void SetExtractBoundaryCells(bool value) { this->ExtractBoundaryCells = value; } + /// @copydoc GetExtractBoundaryCells VTKM_CONT void ExtractBoundaryCellsOn() { this->ExtractBoundaryCells = true; } + /// @copydoc GetExtractBoundaryCells VTKM_CONT void ExtractBoundaryCellsOff() { this->ExtractBoundaryCells = false; } + /// @brief Specify whether to extract cells only on the boundary. + /// + /// When this flag is off (the default), this filter extract the geometry in + /// the region specified by the implicit function. When this flag is on, then + /// only those cells that intersect the surface of the implicit function are + /// extracted. VTKM_CONT bool GetExtractOnlyBoundaryCells() const { return this->ExtractOnlyBoundaryCells; } + /// @brief GetExtractOnlyBoundaryCells VTKM_CONT void SetExtractOnlyBoundaryCells(bool value) { this->ExtractOnlyBoundaryCells = value; } + /// @brief GetExtractOnlyBoundaryCells VTKM_CONT void ExtractOnlyBoundaryCellsOn() { this->ExtractOnlyBoundaryCells = true; } + /// @brief GetExtractOnlyBoundaryCells VTKM_CONT void ExtractOnlyBoundaryCellsOff() { this->ExtractOnlyBoundaryCells = false; } diff --git a/vtkm/filter/entity_extraction/ExtractPoints.h b/vtkm/filter/entity_extraction/ExtractPoints.h index 3af0f13be..b6549561d 100644 --- a/vtkm/filter/entity_extraction/ExtractPoints.h +++ b/vtkm/filter/entity_extraction/ExtractPoints.h @@ -24,34 +24,53 @@ namespace entity_extraction { /// @brief Extract only points from a geometry using an implicit function /// -/// /// Extract only the points that are either inside or outside of a /// VTK-m implicit function. Examples include planes, spheres, boxes, /// etc. +/// /// Note that while any geometry type can be provided as input, the output is /// represented by an explicit representation of points using -/// vtkm::cont::CellSetSingleType +/// `vtkm::cont::CellSetSingleType` with one vertex cell per point. class VTKM_FILTER_ENTITY_EXTRACTION_EXPORT ExtractPoints : public vtkm::filter::FilterField { public: - /// When CompactPoints is set, instead of copying the points and point fields - /// from the input, the filter will create new compact fields without the unused elements + /// @brief Option to remove unused points and compact result int a smaller array. + /// + /// When CompactPoints is on, instead of copying the points and point fields + /// from the input, the filter will create new compact fields without the + /// unused elements. + /// When off (the default), unused points will remain listed in the topology, + /// but point fields and coordinate systems will be shallow-copied to the output. VTKM_CONT bool GetCompactPoints() const { return this->CompactPoints; } + /// @copydoc GetCompactPoints VTKM_CONT void SetCompactPoints(bool value) { this->CompactPoints = value; } - /// Set the volume of interest to extract + /// @brief Specifies the implicit function to be used to perform extract points. + /// + /// Only a limited number of implicit functions are supported. See + /// `vtkm::ImplicitFunctionGeneral` for information on which ones. + /// void SetImplicitFunction(const vtkm::ImplicitFunctionGeneral& func) { this->Function = func; } const vtkm::ImplicitFunctionGeneral& GetImplicitFunction() const { return this->Function; } + /// @brief Specify the region of the implicit function to keep points. + /// + /// Determines whether to extract the points that are on the inside of the implicit + /// function (where the function is less than 0) or the outside (where the function is + /// greater than 0). This flag is true by default (i.e., the interior of the implicit + /// function will be extracted). VTKM_CONT bool GetExtractInside() const { return this->ExtractInside; } + /// @copydoc GetExtractInside VTKM_CONT void SetExtractInside(bool value) { this->ExtractInside = value; } + /// @copydoc GetExtractInside VTKM_CONT void ExtractInsideOn() { this->ExtractInside = true; } + /// @copydoc GetExtractInside VTKM_CONT void ExtractInsideOff() { this->ExtractInside = false; } diff --git a/vtkm/filter/entity_extraction/ExtractStructured.h b/vtkm/filter/entity_extraction/ExtractStructured.h index 1d01bb160..c9e590ee5 100644 --- a/vtkm/filter/entity_extraction/ExtractStructured.h +++ b/vtkm/filter/entity_extraction/ExtractStructured.h @@ -21,7 +21,7 @@ namespace filter { namespace entity_extraction { -/// \brief Select piece (e.g., volume of interest) and/or subsample structured points dataset +/// \brief Select a piece (e.g., volume of interest) and/or subsample structured points dataset /// /// Select or subsample a portion of an input structured dataset. The selected /// portion of interested is referred to as the Volume Of Interest, or VOI. @@ -40,51 +40,72 @@ namespace entity_extraction class VTKM_FILTER_ENTITY_EXTRACTION_EXPORT ExtractStructured : public vtkm::filter::FilterField { public: - // Set the bounding box for the volume of interest + /// @brief Specifies what volume of interest (VOI) should be extracted by the filter. + /// + /// The VOI is specified using the 3D indices of the structured mesh. Meshes with fewer + /// than 3 dimensions will ignore the extra dimensions in the VOI. The VOI is inclusive + /// on the minium index and exclusive on the maximum index. + /// + /// By default the VOI is the entire input. VTKM_CONT vtkm::RangeId3 GetVOI() const { return this->VOI; } + /// @copydoc GetVOI VTKM_CONT void SetVOI(vtkm::Id i0, vtkm::Id i1, vtkm::Id j0, vtkm::Id j1, vtkm::Id k0, vtkm::Id k1) { this->VOI = vtkm::RangeId3(i0, i1, j0, j1, k0, k1); } + /// @copydoc GetVOI VTKM_CONT void SetVOI(vtkm::Id extents[6]) { this->VOI = vtkm::RangeId3(extents); } + /// @copydoc GetVOI VTKM_CONT void SetVOI(vtkm::Id3 minPoint, vtkm::Id3 maxPoint) { this->VOI = vtkm::RangeId3(minPoint, maxPoint); } + /// @copydoc GetVOI VTKM_CONT void SetVOI(const vtkm::RangeId3& voi) { this->VOI = voi; } - /// Get the Sampling rate + /// @brief Specifies the sample rate of the VOI. + /// + /// The input data can be subsampled by selecting every n-th value. + /// The sampling can be different in each dimension. + /// The default sampling rate is (1,1,1), meaning that no subsampling will occur. VTKM_CONT vtkm::Id3 GetSampleRate() const { return this->SampleRate; } - /// Set the Sampling rate + /// @copydoc GetSampleRate VTKM_CONT void SetSampleRate(vtkm::Id i, vtkm::Id j, vtkm::Id k) { this->SampleRate = vtkm::Id3(i, j, k); } - /// Set the Sampling rate + /// @copydoc GetSampleRate VTKM_CONT void SetSampleRate(vtkm::Id3 sampleRate) { this->SampleRate = sampleRate; } - /// Get if we should include the outer boundary on a subsample + // Get if we should include the outer boundary on a subsample + // (NOTE: This method is deprecated because it is not clear from either + // the documentation or the source code what the intention of this feature + // is. If your are using this method somewhere and think it should remain, + // please open a merge request to "de-deprecate" it and add a test and + // documentation of the expected behavior.) + VTKM_DEPRECATED(2.2) VTKM_CONT bool GetIncludeBoundary() const { return this->IncludeBoundary; } - /// Set if we should include the outer boundary on a subsample + // Set if we should include the outer boundary on a subsample + VTKM_DEPRECATED(2.2) VTKM_CONT void SetIncludeBoundary(bool value) { this->IncludeBoundary = value; } - /// Set if VOI is specified in global (rather than in local) point indices - /// (NOTE: Depracted this method since this does not seem to work as - /// expected and there are no tests for it. Furthermore, neither VTK-m nor - /// VTK-h/Ascent seem to use this method. If your are using this method - /// somewhere else and think it should remain, please open a merge request to - /// "de-deprecate" it and add a test and documentation of the expected - /// behavior.) + // Set if VOI is specified in global (rather than in local) point indices + // (NOTE: Deprecated this method since this does not seem to work as + // expected and there are no tests for it. Furthermore, neither VTK-m nor + // VTK-h/Ascent seem to use this method. If your are using this method + // somewhere else and think it should remain, please open a merge request to + // "de-deprecate" it and add a test and documentation of the expected + // behavior.) VTKM_DEPRECATED(2.1) VTKM_CONT void SetIncludeOffset(bool value) { this->IncludeOffset = value; } diff --git a/vtkm/filter/entity_extraction/Threshold.h b/vtkm/filter/entity_extraction/Threshold.h index 3542249cb..0b2e7d603 100644 --- a/vtkm/filter/entity_extraction/Threshold.h +++ b/vtkm/filter/entity_extraction/Threshold.h @@ -20,67 +20,91 @@ namespace filter { namespace entity_extraction { -/// \brief Extracts cells which satisfy threshold criterion + +/// \brief Extracts cells that satisfy a threshold criterion. /// /// Extracts all cells from any dataset type that satisfy a threshold criterion. -/// The output of this filter is an permutation of the input dataset. +/// The output of this filter stores its connectivity in a `vtkm::cont::CellSetExplicit<>` +/// regardless of the input dataset type or which cells are passed. /// -/// You can threshold either on point or cell fields +/// You can threshold either on point or cell fields. If thresholding on point fields, +/// you must specify whether a cell should be kept if some but not all of its incident +/// points meet the criteria. +/// +/// Although `Threshold` is primarily designed for scalar fields, there is support for +/// thresholding on 1 or all of the components in a vector field. See the +/// `SetComponentToTest()`, `SetComponentToTestToAny()`, and `SetComponentToTestToAll()` +/// methods for more information. +/// +/// Use `SetActiveField()` and related methods to set the field to threshold on. class VTKM_FILTER_ENTITY_EXTRACTION_EXPORT Threshold : public vtkm::filter::FilterField { public: - VTKM_CONT - void SetLowerThreshold(vtkm::Float64 value) { this->LowerValue = value; } - VTKM_CONT - void SetUpperThreshold(vtkm::Float64 value) { this->UpperValue = value; } + /// @brief Specifies the lower scalar value. + /// Any cells where the scalar field is less than this value are removed. + VTKM_CONT void SetLowerThreshold(vtkm::Float64 value) { this->LowerValue = value; } + /// @brief Specifies the upper scalar value. + /// Any cells where the scalar field is more than this value are removed. + VTKM_CONT void SetUpperThreshold(vtkm::Float64 value) { this->UpperValue = value; } - VTKM_CONT - vtkm::Float64 GetLowerThreshold() const { return this->LowerValue; } - VTKM_CONT - vtkm::Float64 GetUpperThreshold() const { return this->UpperValue; } + /// @copydoc SetLowerThreshold + VTKM_CONT vtkm::Float64 GetLowerThreshold() const { return this->LowerValue; } + /// @copydoc SetUpperThreshold + VTKM_CONT vtkm::Float64 GetUpperThreshold() const { return this->UpperValue; } - /// @brief Set the threshold criterion to pass any value <= to the specified value. - VTKM_CONT - void SetThresholdBelow(vtkm::Float64 value); + /// @brief Sets the threshold criterion to pass any value less than or equal to @a value. + VTKM_CONT void SetThresholdBelow(vtkm::Float64 value); - /// @brief Set the threshold criterion to pass any value >= to the specified value. - VTKM_CONT - void SetThresholdAbove(vtkm::Float64 value); + /// @brief Sets the threshold criterion to pass any value greater than or equal to @a value. + VTKM_CONT void SetThresholdAbove(vtkm::Float64 value); /// @brief Set the threshold criterion to pass any value between (inclusive) the given values. - VTKM_CONT - void SetThresholdBetween(vtkm::Float64 value1, vtkm::Float64 value2); + /// + /// This method is equivalent to calling `SetLowerThreshold(value1)` and + /// `SetUpperThreshold(value2)`. + VTKM_CONT void SetThresholdBetween(vtkm::Float64 value1, vtkm::Float64 value2); - ///@{ - /// @brief For multi-component fields, select how to apply the threshold criterion. - /// The default is to test the 0th component. - VTKM_CONT - void SetComponentToTest(vtkm::IdComponent component) + /// @brief Specifies that the threshold criteria should be applied to a specific vector component. + /// + /// When thresholding on a vector field (which has more than one component per entry), + /// the `Threshold` filter will by default compare the threshold criterion to the first + /// component of the vector (component index 0). Use this method to change the component + /// to test against. + VTKM_CONT void SetComponentToTest(vtkm::IdComponent component) { this->ComponentMode = Component::Selected; this->SelectedComponent = component; } - VTKM_CONT - void SetComponentToTestToAny() { this->ComponentMode = Component::Any; } - VTKM_CONT - void SetComponentToTestToAll() { this->ComponentMode = Component::All; } - ///@} + /// @brief Specifies that the threshold criteria should be applied to a specific vector component. + /// + /// This method sets that the threshold criteria should be applied to all the components of + /// the input vector field and a cell will pass if @e any the components match. + VTKM_CONT void SetComponentToTestToAny() { this->ComponentMode = Component::Any; } + /// @brief Specifies that the threshold criteria should be applied to a specific vector component. + /// + /// This method sets that the threshold criteria should be applied to all the components of + /// the input vector field and a cell will pass if @e all the components match. + VTKM_CONT void SetComponentToTestToAll() { this->ComponentMode = Component::All; } - /// @brief If using field from point data, all values for all points in a cell must - /// satisfy the threshold criterion if `AllInRange` is set. Otherwise, just a - /// single point's value satisfying the threshold criterion will extract the cell. - VTKM_CONT - void SetAllInRange(bool value) { this->AllInRange = value; } - VTKM_CONT - bool GetAllInRange() const { return this->AllInRange; } + /// @brief Specify criteria for cells that have some points matching. + /// + /// When thresholding on a point field, each cell must consider the multiple values + /// associated with all incident points. When this flag is false (the default), the + /// cell is passed if @e any of the incident points matches the threshold criterion. + /// When this flag is true, the cell is passed only if \e all the incident points match + /// the threshold criterion. + VTKM_CONT void SetAllInRange(bool value) { this->AllInRange = value; } + /// @copydoc SetAllInRange + VTKM_CONT bool GetAllInRange() const { return this->AllInRange; } - /// @brief Invert the threshold result, i.e. cells that would have been in the output with this - /// option off are excluded, while cells that would have been excluded from the output are - /// included. - VTKM_CONT - void SetInvert(bool value) { this->Invert = value; } - VTKM_CONT - bool GetInvert() const { return this->Invert; } + /// @brief Inverts the threshold result. + /// + /// When set to true, the threshold result is inverted. That is, cells that would have been + /// in the output with this option set to false (the default) are excluded while cells that + /// would have been excluded from the output are included. + VTKM_CONT void SetInvert(bool value) { this->Invert = value; } + /// @copydoc SetInvert + VTKM_CONT bool GetInvert() const { return this->Invert; } private: VTKM_CONT diff --git a/vtkm/filter/entity_extraction/testing/UnitTestExtractStructuredFilter.cxx b/vtkm/filter/entity_extraction/testing/UnitTestExtractStructuredFilter.cxx index 5ce8805c9..f6cc9d166 100644 --- a/vtkm/filter/entity_extraction/testing/UnitTestExtractStructuredFilter.cxx +++ b/vtkm/filter/entity_extraction/testing/UnitTestExtractStructuredFilter.cxx @@ -376,6 +376,8 @@ public: VTKM_TEST_ASSERT(outCellData.ReadPortal().Get(0) == 16.0f, "Wrong cell field data"); } + VTKM_DEPRECATED_SUPPRESS_BEGIN + // This test repeates TestUniform3D7 but uses deprecated behavior. static void TestUniform3D8() { std::cout << "Testing extract structured uniform" << std::endl; @@ -414,6 +416,7 @@ public: VTKM_TEST_ASSERT(outCellData.ReadPortal().Get(0) == 16.0f, "Wrong cell field data"); VTKM_TEST_ASSERT(outCellData.ReadPortal().Get(3) == 31.0f, "Wrong cell field data"); } + VTKM_DEPRECATED_SUPPRESS_END static void TestRectilinear2D() { diff --git a/vtkm/filter/field_conversion/CellAverage.h b/vtkm/filter/field_conversion/CellAverage.h index d231a41c4..3c2b2bc71 100644 --- a/vtkm/filter/field_conversion/CellAverage.h +++ b/vtkm/filter/field_conversion/CellAverage.h @@ -20,13 +20,18 @@ namespace filter { namespace field_conversion { -/// \brief Point to cell interpolation filter. +/// \brief Point to cell interpolation filter. /// /// CellAverage is a filter that transforms point data (i.e., data /// specified at cell points) into cell data (i.e., data specified per cell). /// The method of transformation is based on averaging the data /// values of all points used by particular cell. /// +/// The point field to convert comes from the active scalars. +/// The default name for the output cell field is the same name as the input +/// point field. The name can be overridden as always using the +/// `SetOutputFieldName()` method. +/// class VTKM_FILTER_FIELD_CONVERSION_EXPORT CellAverage : public vtkm::filter::FilterField { private: diff --git a/vtkm/filter/field_conversion/PointAverage.h b/vtkm/filter/field_conversion/PointAverage.h index 0258a3b26..2013b05f2 100644 --- a/vtkm/filter/field_conversion/PointAverage.h +++ b/vtkm/filter/field_conversion/PointAverage.h @@ -26,6 +26,12 @@ namespace field_conversion /// specified per cell) into point data (i.e., data specified at cell /// points). The method of transformation is based on averaging the data /// values of all cells using a particular point. +/// +/// The cell field to convert comes from the active scalars. +/// The default name for the output cell field is the same name as the input +/// point field. The name can be overridden as always using the +/// `SetOutputFieldName()` method. +/// class VTKM_FILTER_FIELD_CONVERSION_EXPORT PointAverage : public vtkm::filter::FilterField { private: diff --git a/vtkm/filter/field_transform/CompositeVectors.h b/vtkm/filter/field_transform/CompositeVectors.h index 5cc881f06..2481bb4d9 100644 --- a/vtkm/filter/field_transform/CompositeVectors.h +++ b/vtkm/filter/field_transform/CompositeVectors.h @@ -20,12 +20,12 @@ namespace filter namespace field_transform { -/// \brief Combine multiple scalar fields into a single vector field. +/// @brief Combine multiple scalar fields into a single vector field. /// /// Scalar fields are selected as the active input fields, and the combined vector -/// field is set at the output. The `SetFieldNameList` method takes a `std::vector` -/// of field names to use as the component fields. Alternately, the superclass' -/// set active field methods can be used to select the fields independently. +/// field is set at the output. The `SetFieldNameList()` method takes a `std::vector` +/// of field names to use as the component fields. Alternately, the `SetActiveField()` +/// method can be used to select the fields independently. /// /// All of the input fields must be scalar values. The type of the first field /// determines the type of the output vector field. @@ -37,11 +37,14 @@ public: VTKM_CONT CompositeVectors() { this->SetOutputFieldName("CompositedField"); }; - VTKM_CONT - void SetFieldNameList( + /// @brief Specifies the names of the fields to use as components for the output. + VTKM_CONT void SetFieldNameList( const std::vector& fieldNameList, vtkm::cont::Field::Association association = vtkm::cont::Field::Association::Any); + /// @brief The number of fields specified as inputs. + /// + /// This will be the number of components in the generated field. VTKM_CONT vtkm::IdComponent GetNumberOfFields() const; private: diff --git a/vtkm/filter/field_transform/CylindricalCoordinateTransform.h b/vtkm/filter/field_transform/CylindricalCoordinateTransform.h index ed049a09b..1b460c4ba 100644 --- a/vtkm/filter/field_transform/CylindricalCoordinateTransform.h +++ b/vtkm/filter/field_transform/CylindricalCoordinateTransform.h @@ -20,16 +20,24 @@ namespace filter { namespace field_transform { -/// \brief + +/// @brief Transform coordinates between Cartesian and cylindrical. +/// +/// By default, this filter will transform the first coordinate system, but +/// this can be changed by setting the active field. +/// +/// The resulting transformation will be set as the first coordinate system +/// in the output. /// -/// Generate a coordinate transformation on coordinates from a dataset. class VTKM_FILTER_FIELD_TRANSFORM_EXPORT CylindricalCoordinateTransform : public vtkm::filter::FilterField { public: VTKM_CONT CylindricalCoordinateTransform(); + /// @brief Establish a transformation from Cartesian to cylindrical coordinates. VTKM_CONT void SetCartesianToCylindrical() { CartesianToCylindrical = true; } + /// @brief Establish a transformation from cylindrical to Cartesian coordiantes. VTKM_CONT void SetCylindricalToCartesian() { CartesianToCylindrical = false; } private: diff --git a/vtkm/filter/field_transform/FieldToColors.h b/vtkm/filter/field_transform/FieldToColors.h index 67cd104f1..ea0b9dea8 100644 --- a/vtkm/filter/field_transform/FieldToColors.h +++ b/vtkm/filter/field_transform/FieldToColors.h @@ -21,7 +21,10 @@ namespace filter { namespace field_transform { -/// \brief Convert an arbitrary field to an RGB or RGBA field +/// \brief Convert an arbitrary field to an RGB or RGBA field. +/// +/// This filter is useful for generating colors that could be used for rendering or +/// other purposes. /// class VTKM_FILTER_FIELD_TRANSFORM_EXPORT FieldToColors : public vtkm::filter::FilterField { @@ -29,47 +32,102 @@ public: VTKM_CONT explicit FieldToColors(const vtkm::cont::ColorTable& table = vtkm::cont::ColorTable()); + // Documentation of enumerations is behaving a little weird in Doxygen (version 1.9.7). + // You cannot have a blank line in the documentation. Everything below it will be treated + // as preformatted text. Also, the first line always seem to behave like `@brief` is used + // even when it is not. It's easier to just document an associated method and copy the + // documentation + + /// @brief Identifiers used to specify how `FieldToColors` should treat its input scalars. enum struct InputMode { + /// @copydoc FieldToColors::SetMappingToScalar Scalar, + /// @copydoc FieldToColors::SetMappingToMagnitude Magnitude, + /// @copydoc FieldToColors::SetMappingToComponent Component, }; + /// @brief Identifiers used to specify what output `FieldToColors` will generate. enum struct OutputMode { + /// @copydoc FieldToColors::SetOutputToRGB() RGB, - RGBA + /// @copydoc FieldToColors::SetOutputToRGBA() + RGBA, }; + /// @brief Specifies the `vtkm::cont::ColorTable` object to use to map field values to colors. void SetColorTable(const vtkm::cont::ColorTable& table) { this->Table = table; this->ModifiedCount = -1; } + /// @copydoc SetColorTable const vtkm::cont::ColorTable& GetColorTable() const { return this->Table; } + /// @brief Specify the mapping mode. void SetMappingMode(InputMode mode) { this->InputModeType = mode; } + /// @brief Treat the field as a scalar field. + /// + /// It is an error to provide a field of any type that cannot be directly converted + /// to a basic floating point number (such as a vector). void SetMappingToScalar() { this->InputModeType = InputMode::Scalar; } + /// @brief Map the magnitude of the field. + /// + /// Given a vector field, the magnitude of each field value is taken before looking it up + /// in the color table. void SetMappingToMagnitude() { this->InputModeType = InputMode::Magnitude; } + /// @brief Map a component of a vector field as if it were a scalar. + /// + /// Given a vector field, a particular component is looked up in the color table as if + /// that component were in a scalar field. The component to map is selected with + /// `SetMappingComponent()`. void SetMappingToComponent() { this->InputModeType = InputMode::Component; } + /// @brief Specify the mapping mode. InputMode GetMappingMode() const { return this->InputModeType; } + /// @brief Returns true if this filter is in scalar mapping mode. bool IsMappingScalar() const { return this->InputModeType == InputMode::Scalar; } + /// @brief Returns true if this filter is in magnitude mapping mode. bool IsMappingMagnitude() const { return this->InputModeType == InputMode::Magnitude; } + /// @brief Returns true if this filter is vector component mapping mode. bool IsMappingComponent() const { return this->InputModeType == InputMode::Component; } + /// @brief Specifies the component of the vector to use in the mapping. + /// + /// This only has an effect if the input mapping mode is set to + /// `FieldToColors::InputMode::Component`. void SetMappingComponent(vtkm::IdComponent comp) { this->Component = comp; } + /// @copydoc SetMappingComponent vtkm::IdComponent GetMappingComponent() const { return this->Component; } + /// @brief Specify the output mode. void SetOutputMode(OutputMode mode) { this->OutputModeType = mode; } + /// @brief Write out RGB fixed precision color values. + /// + /// Output colors are represented as RGB values with each component represented by an + /// unsigned byte. Specifically, these are `vtkm::Vec3ui_8` values. void SetOutputToRGB() { this->OutputModeType = OutputMode::RGB; } + /// @brief Write out RGBA fixed precision color values. + /// + /// Output colors are represented as RGBA values with each component represented by an + /// unsigned byte. Specifically, these are `vtkm::Vec4ui_8` values. void SetOutputToRGBA() { this->OutputModeType = OutputMode::RGBA; } + /// @brief Specify the output mode. OutputMode GetOutputMode() const { return this->OutputModeType; } + /// @brief Returns true if this filter is in RGB output mode. bool IsOutputRGB() const { return this->OutputModeType == OutputMode::RGB; } + /// @brief Returns true if this filter is in RGBA output mode. bool IsOutputRGBA() const { return this->OutputModeType == OutputMode::RGBA; } - + /// @brief Specifies how many samples to use when looking up color values. + /// + /// The implementation of `FieldToColors` first builds an array of color samples to quickly + /// look up colors for particular values. The size of this lookup array can be adjusted with + /// this parameter. By default, an array of 256 colors is used. void SetNumberOfSamplingPoints(vtkm::Int32 count); + /// @copydoc SetNumberOfSamplingPoints vtkm::Int32 GetNumberOfSamplingPoints() const { return this->SampleCount; } private: @@ -84,6 +142,7 @@ private: vtkm::Int32 SampleCount = 256; vtkm::Id ModifiedCount = -1; }; + } // namespace field_transform } // namespace filter } // namespace vtkm diff --git a/vtkm/filter/field_transform/GenerateIds.h b/vtkm/filter/field_transform/GenerateIds.h index def7450fa..b437af153 100644 --- a/vtkm/filter/field_transform/GenerateIds.h +++ b/vtkm/filter/field_transform/GenerateIds.h @@ -19,12 +19,12 @@ namespace filter { namespace field_transform { -/// \brief Adds fields to a `DataSet` that give the ids for the points and cells. +/// \brief Adds fields to a `vtkm::cont::DataSet` that give the ids for the points and cells. /// /// This filter will add (by default) a point field named `pointids` that gives the /// index of the associated point and likewise a cell field named `cellids` for the /// associated cell indices. These fields are useful for tracking the provenance of -/// the elements of a `DataSet` as it gets manipulated by filters. It is also +/// the elements of a `vtkm::cont::DataSet` as it gets manipulated by filters. It is also /// convenient for adding indices to operations designed for fields and generally /// creating test data. /// @@ -37,45 +37,40 @@ class VTKM_FILTER_FIELD_TRANSFORM_EXPORT GenerateIds : public vtkm::filter::Filt bool UseFloat = false; public: - /// \{ - /// \brief The name given to the generated point field. + /// @brief The name given to the generated point field. /// /// By default, the name is `pointids`. /// const std::string& GetPointFieldName() const { return this->PointFieldName; } + /// @copydoc GetPointFieldName void SetPointFieldName(const std::string& name) { this->PointFieldName = name; } - /// \} - /// \{ - /// \brief The name given to the generated cell field. + /// @brief The name given to the generated cell field. /// /// By default, the name is `cellids`. /// const std::string& GetCellFieldName() const { return this->CellFieldName; } + /// @copydoc GetCellFieldName void SetCellFieldName(const std::string& name) { this->CellFieldName = name; } - /// \} - /// \{ - /// \brief Specify whether the point id field is generated. + /// @brief Specify whether the point id field is generated. /// /// When `GeneratePointIds` is `true` (the default), a field echoing the point /// indices is generated. When set to `false`, this output is not created. /// bool GetGeneratePointIds() const { return this->GeneratePointIds; } + /// @copydoc GetGeneratePointIds void SetGeneratePointIds(bool flag) { this->GeneratePointIds = flag; } - /// \} - /// \{ /// \brief Specify whether the cell id field is generated. /// /// When `GenerateCellIds` is `true` (the default), a field echoing the cell /// indices is generated. When set to `false`, this output is not created. /// bool GetGenerateCellIds() const { return this->GenerateCellIds; } + /// @copydoc GetGenerateCellIds void SetGenerateCellIds(bool flag) { this->GenerateCellIds = flag; } - /// \} - /// \{ /// \brief Specify whether the generated fields should be integer or float. /// /// When `UseFloat` is `false` (the default), then the fields generated will have @@ -83,6 +78,7 @@ public: /// with type `vtkm::FloatDefault`. /// bool GetUseFloat() const { return this->UseFloat; } + /// @copydoc GetUseFloat void SetUseFloat(bool flag) { this->UseFloat = flag; } private: diff --git a/vtkm/filter/field_transform/LogValues.h b/vtkm/filter/field_transform/LogValues.h index ec2fec7a3..daf871594 100644 --- a/vtkm/filter/field_transform/LogValues.h +++ b/vtkm/filter/field_transform/LogValues.h @@ -20,33 +20,64 @@ namespace filter namespace field_transform { -/// \brief Adds field to a `DataSet` that gives the log values for the user specified field. +/// \brief Adds field to a `vtkm::cont::DataSet` that gives the log values for the user specified field. /// -/// This filter use the ActiveField defined in the FilterField to store the log values. +/// By default, `LogValues` takes a natural logarithm (of base e). The base of the +/// logarithm can be set to one of the bases listed in `LogBase` with `SetBaseValue()`. +/// +/// Logarithms are often used to rescale data to simultaneously show data at different +/// orders of magnitude. It allows small changes in small numbers be visible next to +/// much larger numbers with less precision. One problem with this approach is if there +/// exist numbers very close to zero, the scale at the low range could make all but the +/// smallest numbers comparatively hard to see. Thus, `LogValues` supports setting a +/// minimum value (with `SetMinValue()`) that will clamp any smaller values to that. /// class VTKM_FILTER_FIELD_TRANSFORM_EXPORT LogValues : public vtkm::filter::FilterField { public: + /// @brief Identifies a type of logarithm as specified by its base. enum struct LogBase { + /// @copydoc LogValues::SetBaseValueToE E, + /// @copydoc LogValues::SetBaseValueTo2 TWO, + /// @copydoc LogValues::SetBaseValueTo10 TEN }; - /// \{ - /// \brief The base value given to the log filter. - /// - const LogBase& GetBaseValue() const { return this->BaseValue; } - void SetBaseValue(const LogBase& base) { this->BaseValue = base; } - /// \} + /// @brief Specify the base of the logarithm. + VTKM_CONT const LogBase& GetBaseValue() const { return this->BaseValue; } + /// @brief Specify the base of the logarithm. + VTKM_CONT void SetBaseValue(const LogBase& base) { this->BaseValue = base; } - /// \{ - /// \brief The min value for executing the log filter. + /// @brief Take the natural logarithm. /// + /// The logarithm is set to the mathematical constant e (about 2.718). + /// This is a constant that has many uses in calculus and other mathematics, + /// and a logarithm of base e is often referred to as the "natural" logarithm. + VTKM_CONT void SetBaseValueToE() { this->SetBaseValue(LogBase::E); } + /// @brief Take the base 2 logarithm. + /// + /// The base 2 logarithm is particularly useful for estimating the depth + /// of a binary hierarchy. + VTKM_CONT void SetBaseValueTo2() { this->SetBaseValue(LogBase::TWO); } + /// @brief Take the base 10 logarithm. + /// + /// The base 10 logarithm is handy to convert a number to its order of magnitude + /// based on our standard base 10 human counting system. + VTKM_CONT void SetBaseValueTo10() { this->SetBaseValue(LogBase::TEN); } + + /// @brief Specifies the minimum value to take the logarithm of. + /// + /// Before taking the logarithm, this filter will check the value to this minimum + /// value and clamp it to the minimum value if it is lower. This is useful to + /// prevent values from approching negative infinity. + /// + /// By default, no minimum value is used. vtkm::FloatDefault GetMinValue() const { return this->MinValue; } + /// @copydoc GetMinValue void SetMinValue(const vtkm::FloatDefault& value) { this->MinValue = value; } - /// \} private: vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override; diff --git a/vtkm/filter/field_transform/PointElevation.h b/vtkm/filter/field_transform/PointElevation.h index 91ae47af3..a53cb9746 100644 --- a/vtkm/filter/field_transform/PointElevation.h +++ b/vtkm/filter/field_transform/PointElevation.h @@ -20,33 +20,53 @@ namespace filter { namespace field_transform { -/// \brief generate a scalar field along a specified direction +/// \brief Generate a scalar field along a specified direction /// -/// Generate scalar field from a dataset. -/// The scalar field values lie within a user specified range, and -/// are generated by computing a projection of each dataset point onto -/// a line. The line can be oriented arbitrarily. A typical example is -/// to generate scalars based on elevation or height above a plane. +/// The filter will take a data set and a field of 3 dimensional vectors and compute the +/// distance along a line defined by a low point and a high point. Any point in the plane +/// touching the low point and perpendicular to the line is set to the minimum range value +/// in the elevation whereas any point in the plane touching the high point and +/// perpendicular to the line is set to the maximum range value. All other values are +/// interpolated linearly between these two planes. This filter is commonly used to compute +/// the elevation of points in some direction, but can be repurposed for a variety of measures. +/// +/// The default name for the output field is ``elevation'', but that can be +/// overridden as always using the `SetOutputFieldName()` method. class VTKM_FILTER_FIELD_TRANSFORM_EXPORT PointElevation : public vtkm::filter::FilterField { public: - VTKM_CONT - PointElevation(); + VTKM_CONT PointElevation(); + /// @brief Specify the coordinate of the low point. + /// + /// The plane of low values is defined by the plane that contains the low point and + /// is normal to the direction from the low point to the high point. All vector + /// values on this plane are assigned the low value. VTKM_CONT void SetLowPoint(const vtkm::Vec3f_64& point) { this->LowPoint = point; } + /// @copydoc SetLowPoint VTKM_CONT void SetLowPoint(vtkm::Float64 x, vtkm::Float64 y, vtkm::Float64 z) { this->SetLowPoint({ x, y, z }); } + /// @brief Specify the coordinate of the high point. + /// + /// The plane of high values is defined by the plane that contains the high point and + /// is normal to the direction from the low point to the high point. All vector + /// values on this plane are assigned the high value. VTKM_CONT void SetHighPoint(const vtkm::Vec3f_64& point) { this->HighPoint = point; } + /// @copydoc SetHighPoint VTKM_CONT void SetHighPoint(vtkm::Float64 x, vtkm::Float64 y, vtkm::Float64 z) { this->SetHighPoint({ x, y, z }); } - VTKM_CONT - void SetRange(vtkm::Float64 low, vtkm::Float64 high) + /// @brief Specify the range of values to output. + /// + /// Values at the low plane are given @p low and values at the high plane are given + /// @p high. Values in between the planes have a linearly interpolated value based + /// on the relative distance between the two planes. + VTKM_CONT void SetRange(vtkm::Float64 low, vtkm::Float64 high) { this->RangeLow = low; this->RangeHigh = high; diff --git a/vtkm/filter/field_transform/PointTransform.h b/vtkm/filter/field_transform/PointTransform.h index e56d28021..4e31da7b8 100644 --- a/vtkm/filter/field_transform/PointTransform.h +++ b/vtkm/filter/field_transform/PointTransform.h @@ -23,16 +23,30 @@ namespace filter { namespace field_transform { -/// \brief +/// \brief Perform affine transforms to point coordinates or vector fields. +/// +/// This filter will take a data set and a field of 3 dimensional vectors and perform +/// the specified point transform operation. Several methods are provided to apply +/// many common affine transformations (e.g., translation, rotation, and scale). +/// You can also provide a general 4x4 transformation matrix with `SetTransform()`. +/// +/// The main use case for `PointTransform` is to perform transformations of +/// objects in 3D space, which is done by applying these transforms to the +/// coordinate system. This filter will operate on the `vtkm::cont::CoordinateSystem` +/// of the input data unless a different active field is specified. Likewise, +/// this filter will save its results as the first coordinate system in the output +/// unless `SetChangeCoordinateSystem()` is set to say otherwise. +/// +/// The default name for the output field is "transform", but that can be overridden as +/// always using the `SetOutputFieldName()` method. /// -/// Generate scalar field from a dataset. class VTKM_FILTER_FIELD_TRANSFORM_EXPORT PointTransform : public vtkm::filter::FilterField { public: VTKM_CONT PointTransform(); - //Translation + /// @brief Translates, or moves, each point in the input field by a given direction. VTKM_CONT void SetTranslation(const vtkm::FloatDefault& tx, const vtkm::FloatDefault& ty, const vtkm::FloatDefault& tz) @@ -40,44 +54,61 @@ public: matrix = vtkm::Transform3DTranslate(tx, ty, tz); } - VTKM_CONT void SetTranslation(const vtkm::Vec& v) - { - SetTranslation(v[0], v[1], v[2]); - } + /// @copydoc SetTranslation + VTKM_CONT void SetTranslation(const vtkm::Vec3f& v) { SetTranslation(v[0], v[1], v[2]); } - //Rotation - VTKM_CONT void SetRotation(const vtkm::FloatDefault& angleDegrees, - const vtkm::Vec& axis) + /// @brief Rotate the input field about a given axis. + /// + /// @param[in] angleDegrees The amount of rotation to perform, given in degrees. + /// @param[in] axis The rotation is made around a line that goes through the origin + /// and pointing in this direction in the counterclockwise direction. + VTKM_CONT void SetRotation(const vtkm::FloatDefault& angleDegrees, const vtkm::Vec3f& axis) { matrix = vtkm::Transform3DRotate(angleDegrees, axis); } + /// @brief Rotate the input field about a given axis. + /// + /// The rotation is made around a line that goes through the origin + /// and pointing in the direction specified by @p axisX, @p axisY, + /// and @p axisZ in the counterclockwise direction. + /// + /// @param[in] angleDegrees The amount of rotation to perform, given in degrees. + /// @param[in] axisX The X value of the rotation axis. + /// @param[in] axisY The Y value of the rotation axis. + /// @param[in] axisZ The Z value of the rotation axis. VTKM_CONT void SetRotation(const vtkm::FloatDefault& angleDegrees, - const vtkm::FloatDefault& rx, - const vtkm::FloatDefault& ry, - const vtkm::FloatDefault& rz) + const vtkm::FloatDefault& axisX, + const vtkm::FloatDefault& axisY, + const vtkm::FloatDefault& axisZ) { - SetRotation(angleDegrees, { rx, ry, rz }); + SetRotation(angleDegrees, { axisX, axisY, axisZ }); } + /// @brief Rotate the input field around the X axis by the given degrees. VTKM_CONT void SetRotationX(const vtkm::FloatDefault& angleDegrees) { SetRotation(angleDegrees, 1, 0, 0); } + /// @brief Rotate the input field around the Y axis by the given degrees. VTKM_CONT void SetRotationY(const vtkm::FloatDefault& angleDegrees) { SetRotation(angleDegrees, 0, 1, 0); } + /// @brief Rotate the input field around the Z axis by the given degrees. VTKM_CONT void SetRotationZ(const vtkm::FloatDefault& angleDegrees) { SetRotation(angleDegrees, 0, 0, 1); } - //Scaling + /// @brief Scale the input field. + /// + /// Each coordinate is multiplied by tghe associated scale factor. VTKM_CONT void SetScale(const vtkm::FloatDefault& s) { matrix = vtkm::Transform3DScale(s, s, s); } + /// @copydoc SetScale VTKM_CONT void SetScale(const vtkm::FloatDefault& sx, const vtkm::FloatDefault& sy, const vtkm::FloatDefault& sz) @@ -85,15 +116,27 @@ public: matrix = vtkm::Transform3DScale(sx, sy, sz); } - VTKM_CONT void SetScale(const vtkm::Vec& v) + /// @copydoc SetScale + VTKM_CONT void SetScale(const vtkm::Vec3f& v) { matrix = vtkm::Transform3DScale(v[0], v[1], v[2]); } - //General transformation + /// @brief Set a general transformation matrix. + /// + /// Each field value is multiplied by this 4x4 as a homogeneous coordinate. That is + /// a 1 component is added to the end of each 3D vector to put it in the form [x, y, z, 1]. + /// The matrix is then premultiplied to this as a column vector. + /// + /// The functions in vtkm/Transform3D.h can be used to help build these transform + /// matrices. VTKM_CONT void SetTransform(const vtkm::Matrix& mtx) { matrix = mtx; } + /// @brief Specify whether the result should become the coordinate system of the output. + /// + /// When this flag is on (the default) the first coordinate system in the output + /// `vtkm::cont::DataSet` is set to the transformed point coordinates. void SetChangeCoordinateSystem(bool flag); bool GetChangeCoordinateSystem() const; diff --git a/vtkm/filter/field_transform/SphericalCoordinateTransform.h b/vtkm/filter/field_transform/SphericalCoordinateTransform.h index b8d089e3d..d94c56ba3 100644 --- a/vtkm/filter/field_transform/SphericalCoordinateTransform.h +++ b/vtkm/filter/field_transform/SphericalCoordinateTransform.h @@ -21,13 +21,23 @@ namespace filter namespace field_transform { +/// @brief Transform coordinates between Cartesian and spherical. +/// +/// By default, this filter will transform the first coordinate system, but +/// this can be changed by setting the active field. +/// +/// The resulting transformation will be set as the first coordinate system +/// in the output. +/// class VTKM_FILTER_FIELD_TRANSFORM_EXPORT SphericalCoordinateTransform : public vtkm::filter::FilterField { public: VTKM_CONT SphericalCoordinateTransform(); + /// @brief Establish a transformation from Cartesian to spherical coordinates. VTKM_CONT void SetCartesianToSpherical() { CartesianToSpherical = true; } + /// @brief Establish a transformation from spherical to Cartesian coordiantes. VTKM_CONT void SetSphericalToCartesian() { CartesianToSpherical = false; } private: diff --git a/vtkm/filter/flow/FilterParticleAdvection.h b/vtkm/filter/flow/FilterParticleAdvection.h index a95760465..aef43bf37 100644 --- a/vtkm/filter/flow/FilterParticleAdvection.h +++ b/vtkm/filter/flow/FilterParticleAdvection.h @@ -35,18 +35,32 @@ public: VTKM_CONT bool CanThread() const override { return false; } - VTKM_CONT - void SetStepSize(vtkm::FloatDefault s) { this->StepSize = s; } + /// @brief Specifies the step size used for the numerical integrator. + /// + /// The numerical integrators operate by advancing each particle by a finite amount. + /// This parameter defines the distance to advance each time. Smaller values are + /// more accurate but take longer to integrate. An appropriate step size is usually + /// around the size of each cell. + VTKM_CONT void SetStepSize(vtkm::FloatDefault s) { this->StepSize = s; } - VTKM_CONT - void SetNumberOfSteps(vtkm::Id n) { this->NumberOfSteps = n; } + /// @brief Specifies the maximum number of integration steps for each particle. + /// + /// Some particle paths may loop and continue indefinitely. This parameter sets an upper + /// limit on the total length of advection. + VTKM_CONT void SetNumberOfSteps(vtkm::Id n) { this->NumberOfSteps = n; } + /// @brief Specify the seed locations for the particle advection. + /// + /// Each seed represents one particle that is advected by the vector field. + /// The particles are represented by a `vtkm::Particle` object or similar + /// type of object (such as `vtkm::ChargedParticle`). template VTKM_CONT void SetSeeds(vtkm::cont::ArrayHandle& seeds) { this->Seeds = seeds; } + /// @copydoc SetSeeds template VTKM_CONT void SetSeeds(const std::vector& seeds, vtkm::CopyFlag copyFlag = vtkm::CopyFlag::On) diff --git a/vtkm/filter/flow/FilterParticleAdvectionUnsteadyState.h b/vtkm/filter/flow/FilterParticleAdvectionUnsteadyState.h index d826b637d..865b05ccb 100644 --- a/vtkm/filter/flow/FilterParticleAdvectionUnsteadyState.h +++ b/vtkm/filter/flow/FilterParticleAdvectionUnsteadyState.h @@ -24,6 +24,8 @@ namespace flow template struct FlowTraits; +/// @brief Superclass for filters that operate on flow that changes over time. +/// template class VTKM_FILTER_FLOW_EXPORT FilterParticleAdvectionUnsteadyState : public FilterParticleAdvection { @@ -33,12 +35,20 @@ public: using TerminationType = typename FlowTraits::TerminationType; using AnalysisType = typename FlowTraits::AnalysisType; + /// @brief Specifies time value for the input data set. + /// + /// This is the data set that passed into the `Execute()` method. VTKM_CONT void SetPreviousTime(vtkm::FloatDefault t1) { this->Time1 = t1; } + /// @brief Specifies time value for the next data set. + /// + /// This is the data set passed into `SetNextDataSet()` @e before `Execute()` is called. VTKM_CONT void SetNextTime(vtkm::FloatDefault t2) { this->Time2 = t2; } + /// @brief Specifies the data for the later time step. VTKM_CONT void SetNextDataSet(const vtkm::cont::DataSet& ds) { this->Input2 = { ds }; } + /// @brief Specifies the data for the later time step. VTKM_CONT void SetNextDataSet(const vtkm::cont::PartitionedDataSet& pds) { this->Input2 = pds; } private: diff --git a/vtkm/filter/flow/LagrangianStructures.h b/vtkm/filter/flow/LagrangianStructures.h index 142128b49..6887998d3 100644 --- a/vtkm/filter/flow/LagrangianStructures.h +++ b/vtkm/filter/flow/LagrangianStructures.h @@ -22,37 +22,84 @@ namespace filter namespace flow { +/// @brief Compute the finite time Lyapunov exponent (FTLE) of a vector field. +/// +/// The FTLE is computed by advecting particles throughout the vector field and analyizing +/// where they diverge or converge. By default, the points of the input `vtkm::cont::DataSet` +/// are all advected for this computation unless an auxiliary grid is established. +/// class VTKM_FILTER_FLOW_EXPORT LagrangianStructures : public vtkm::filter::FilterField { public: VTKM_CONT bool CanThread() const override { return false; } + /// @brief Specifies the step size used for the numerical integrator. + /// + /// The numerical integrators operate by advancing each particle by a finite amount. + /// This parameter defines the distance to advance each time. Smaller values are + /// more accurate but take longer to integrate. An appropriate step size is usually + /// around the size of each cell. void SetStepSize(vtkm::FloatDefault s) { this->StepSize = s; } + /// @copydoc SetStepSize vtkm::FloatDefault GetStepSize() { return this->StepSize; } + /// @brief Specify the maximum number of steps each particle is allowed to traverse. + /// + /// This can limit the total length of displacements used when computing the FTLE. void SetNumberOfSteps(vtkm::Id n) { this->NumberOfSteps = n; } + /// @copydoc SetNumberOfSteps vtkm::Id GetNumberOfSteps() { return this->NumberOfSteps; } + /// @brief Specify the time interval for the advection. + /// + /// The FTLE works by advecting all points a finite distance, and this parameter + /// specifies how far to advect. void SetAdvectionTime(vtkm::FloatDefault advectionTime) { this->AdvectionTime = advectionTime; } + /// @copydoc SetAdvectionTime vtkm::FloatDefault GetAdvectionTime() { return this->AdvectionTime; } + /// @brief Specify whether to use an auxiliary grid. + /// + /// When this flag is off (the default), then the points of the mesh representing the vector + /// field are advected and used for computing the FTLE. However, if the mesh is too coarse, + /// the FTLE will likely be inaccurate. Or if the mesh is unstructured the FTLE may be less + /// efficient to compute. When this flag is on, an auxiliary grid of uniformly spaced points + /// is used for the FTLE computation. void SetUseAuxiliaryGrid(bool useAuxiliaryGrid) { this->UseAuxiliaryGrid = useAuxiliaryGrid; } + /// @copydoc SetUseAuxiliaryGrid bool GetUseAuxiliaryGrid() { return this->UseAuxiliaryGrid; } + /// @brief Specify the dimensions of the auxiliary grid for FTLE calculation. + /// + /// Seeds for advection will be placed along the points of this auxiliary grid. + /// This option has no effect unless the UseAuxiliaryGrid option is on. void SetAuxiliaryGridDimensions(vtkm::Id3 auxiliaryDims) { this->AuxiliaryDims = auxiliaryDims; } + /// @copydoc SetAuxiliaryGridDimensions vtkm::Id3 GetAuxiliaryGridDimensions() { return this->AuxiliaryDims; } + /// @brief Specify whether to use flow maps instead of advection. + /// + /// If the start and end points for FTLE calculation are known already, advection is + /// an unnecessary step. This flag allows users to bypass advection, and instead use + /// a precalculated flow map. By default this option is off. void SetUseFlowMapOutput(bool useFlowMapOutput) { this->UseFlowMapOutput = useFlowMapOutput; } + /// @copydoc SetUseFlowMapOutput bool GetUseFlowMapOutput() { return this->UseFlowMapOutput; } + /// @brief Specify the name of the output field in the data set returned. + /// + /// By default, the field will be named `FTLE`. void SetOutputFieldName(std::string outputFieldName) { this->OutputFieldName = outputFieldName; } + /// @copydoc SetOutputFieldName std::string GetOutputFieldName() { return this->OutputFieldName; } + /// @brief Specify the array representing the flow map output to be used for FTLE calculation. inline void SetFlowMapOutput(vtkm::cont::ArrayHandle& flowMap) { this->FlowMapOutput = flowMap; } + /// @copydoc SetFlowMapOutput inline vtkm::cont::ArrayHandle GetFlowMapOutput() { return this->FlowMapOutput; } private: diff --git a/vtkm/filter/flow/Pathline.h b/vtkm/filter/flow/Pathline.h index 653a3ee9e..898161b65 100644 --- a/vtkm/filter/flow/Pathline.h +++ b/vtkm/filter/flow/Pathline.h @@ -38,11 +38,14 @@ struct FlowTraits using FieldType = vtkm::worklet::flow::VelocityField; }; -/// \brief Advect particles in a vector field. - -/// Takes as input a vector field and seed locations and generates the -/// end points for each seed through the vector field. - +/// \brief Advect particles in a time-varying vector field and display the path they take. +/// +/// This filter takes as input a velocity vector field, changing between two time steps, +/// and seed locations. It then traces the path each seed point would take if moving at +/// the velocity specified by the field. +/// +/// The output of this filter is a `vtkm::cont::DataSet` containing a collection of poly-lines +/// representing the paths the seed particles take. class VTKM_FILTER_FLOW_EXPORT Pathline : public vtkm::filter::flow::FilterParticleAdvectionUnsteadyState { diff --git a/vtkm/filter/flow/StreamSurface.h b/vtkm/filter/flow/StreamSurface.h index 1ad27eb63..e3fbaea88 100644 --- a/vtkm/filter/flow/StreamSurface.h +++ b/vtkm/filter/flow/StreamSurface.h @@ -22,26 +22,44 @@ namespace filter namespace flow { -/// \brief generate streamlines from a vector field. - -/// Takes as input a vector field and seed locations and generates the -/// paths taken by the seeds through the vector field. - +/// \brief Generate stream surfaces from a vector field. +/// +/// This filter takes as input a velocity vector field and seed locations. The seed locations +/// should be arranged in a line or curve. The filter then traces the path each seed point +/// would take if moving at the velocity specified by the field and connects all the lines +/// together into a surface. Mathematically, this is the surface that is tangent to the +/// velocity field everywhere. +/// +/// The output of this filter is a `vtkm::cont::DataSet` containing a mesh for the created +/// surface. class VTKM_FILTER_FLOW_EXPORT StreamSurface : public vtkm::filter::FilterField { public: - VTKM_CONT - void SetStepSize(vtkm::FloatDefault s) { this->StepSize = s; } + /// @brief Specifies the step size used for the numerical integrator. + /// + /// The numerical integrators operate by advancing each particle by a finite amount. + /// This parameter defines the distance to advance each time. Smaller values are + /// more accurate but take longer to integrate. An appropriate step size is usually + /// around the size of each cell. + VTKM_CONT void SetStepSize(vtkm::FloatDefault s) { this->StepSize = s; } - VTKM_CONT - void SetNumberOfSteps(vtkm::Id n) { this->NumberOfSteps = n; } + /// @brief Specifies the maximum number of integration steps for each particle. + /// + /// Some particle paths may loop and continue indefinitely. This parameter sets an upper + /// limit on the total length of advection. + VTKM_CONT void SetNumberOfSteps(vtkm::Id n) { this->NumberOfSteps = n; } + /// @brief Specify the seed locations for the particle advection. + /// + /// Each seed represents one particle that is advected by the vector field. + /// The particles are represented by a `vtkm::Particle` object. template VTKM_CONT void SetSeeds(vtkm::cont::ArrayHandle& seeds) { this->Seeds = seeds; } + /// @copydoc SetSeeds template VTKM_CONT void SetSeeds(const std::vector& seeds, vtkm::CopyFlag copyFlag = vtkm::CopyFlag::On) diff --git a/vtkm/filter/flow/Streamline.h b/vtkm/filter/flow/Streamline.h index 1ebd4821e..c398958c9 100644 --- a/vtkm/filter/flow/Streamline.h +++ b/vtkm/filter/flow/Streamline.h @@ -38,11 +38,14 @@ struct FlowTraits using FieldType = vtkm::worklet::flow::VelocityField; }; -/// \brief Advect particles in a vector field. - -/// Takes as input a vector field and seed locations and generates the -/// end points for each seed through the vector field. - +/// \brief Advect particles in a vector field and display the path they take. +/// +/// This filter takes as input a velocity vector field and seed locations. It then traces the +/// path each seed point would take if moving at the velocity specified by the field. +/// Mathematically, this is the curve that is tangent to the velocity field everywhere. +/// +/// The output of this filter is a `vtkm::cont::DataSet` containing a collection of poly-lines +/// representing the paths the seed particles take. class VTKM_FILTER_FLOW_EXPORT Streamline : public vtkm::filter::flow::FilterParticleAdvectionSteadyState { diff --git a/vtkm/filter/geometry_refinement/ConvertToPointCloud.h b/vtkm/filter/geometry_refinement/ConvertToPointCloud.h index f231e00c5..cb7dcc6a0 100644 --- a/vtkm/filter/geometry_refinement/ConvertToPointCloud.h +++ b/vtkm/filter/geometry_refinement/ConvertToPointCloud.h @@ -21,7 +21,7 @@ namespace filter namespace geometry_refinement { -/// \brief Convert a `DataSet` to a point cloud. +/// @brief Convert a `DataSet` to a point cloud. /// /// A point cloud in VTK-m is represented as a data set with "vertex" shape cells. /// This filter replaces the `CellSet` in a `DataSet` with a `CellSet` of only @@ -40,7 +40,6 @@ class VTKM_FILTER_GEOMETRY_REFINEMENT_EXPORT ConvertToPointCloud : public vtkm:: bool AssociateFieldsWithCells = false; public: - ///@{ /// By default, all the input point fields are kept as point fields in the output. /// However, the output has exactly one cell per point and it might be easier to /// treat the fields as cell fields. When this flag is turned on, the point field @@ -50,8 +49,8 @@ public: /// fields. It is not valid to set a cell field as the point coordinates. /// VTKM_CONT void SetAssociateFieldsWithCells(bool flag) { this->AssociateFieldsWithCells = flag; } + /// @copydoc SetAssociateFieldsWithCells VTKM_CONT bool GetAssociateFieldsWithCells() const { return this->AssociateFieldsWithCells; } - ///@} protected: VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override; diff --git a/vtkm/filter/geometry_refinement/Shrink.h b/vtkm/filter/geometry_refinement/Shrink.h index 173865f1c..8bc01b4f4 100644 --- a/vtkm/filter/geometry_refinement/Shrink.h +++ b/vtkm/filter/geometry_refinement/Shrink.h @@ -20,7 +20,8 @@ namespace filter { namespace geometry_refinement { -/// \brief Shrink cells of an arbitrary dataset by a constant factor +/// \brief Shrink cells of an arbitrary dataset by a constant factor. +/// /// The Shrink filter shrinks the cells of a DataSet towards their centroid, /// computed as the average position of the cell points. /// This filter disconnects the cells, duplicating the points connected to multiple cells. @@ -28,14 +29,18 @@ namespace geometry_refinement class VTKM_FILTER_GEOMETRY_REFINEMENT_EXPORT Shrink : public vtkm::filter::FilterField { public: - VTKM_CONT - void SetShrinkFactor(const vtkm::FloatDefault& factor) + /// @brief Specify the scale factor to size each cell. + /// + /// The shrink factor specifies the ratio of the shrunk cell to its original size. + /// This value must be between 0 and 1. + /// A value of 1 is the same size as the input, and a value of 0 shrinks each cell to a point. + VTKM_CONT void SetShrinkFactor(vtkm::FloatDefault factor) { this->ShrinkFactor = vtkm::Min(vtkm::Max(0, factor), 1); // Clamp shrink factor value } - VTKM_CONT - const vtkm::FloatDefault& GetShrinkFactor() const { return this->ShrinkFactor; } + /// @copydoc SetShrinkFactor + VTKM_CONT vtkm::FloatDefault GetShrinkFactor() const { return this->ShrinkFactor; } private: VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override; diff --git a/vtkm/filter/geometry_refinement/SplitSharpEdges.h b/vtkm/filter/geometry_refinement/SplitSharpEdges.h index a760e3c0e..59ac60d61 100644 --- a/vtkm/filter/geometry_refinement/SplitSharpEdges.h +++ b/vtkm/filter/geometry_refinement/SplitSharpEdges.h @@ -20,27 +20,38 @@ namespace filter { namespace geometry_refinement { -/// \brief Split sharp manifold edges where the feature angle between the -/// adjacent surfaces are larger than the threshold value +/// @brief Split sharp polygon mesh edges with a large feature angle between the adjacent cells. +/// +/// Split sharp manifold edges where the feature angle between the adjacent polygonal cells +/// are larger than a threshold value. The feature angle is the angle between the normals of +/// the two polygons. Two polygons on the same plane have a feature angle of 0. Perpendicular +/// polygons have a feature angle of 90 degrees. +/// +/// When an edge is split, it adds a new point to the coordinates and updates the connectivity +/// of an adjacent surface. For example, consider two adjacent triangles (0,1,2) and (2,1,3) +/// where edge (1,2) needs to be split. Two new points 4 (duplication of point 1) and 5 +/// (duplication of point 2) would be added and the later triangle's connectivity would be +/// changed to (5,4,3). By default, all old point's fields would be copied to the new point. +/// +/// Note that "split" edges do not have space added between them. They are still adjacent +/// visually, but the topology becomes disconnectered there. Splitting sharp edges is most +/// useful to duplicate normal shading vectors to make a sharp shading effect. /// -/// Split sharp manifold edges where the feature angle between the adjacent -/// surfaces are larger than the threshold value. When an edge is split, it -/// would add a new point to the coordinates and update the connectivity of -/// an adjacent surface. -/// Ex. there are two adjacent triangles(0,1,2) and (2,1,3). Edge (1,2) needs -/// to be split. Two new points 4(duplication of point 1) an 5(duplication of point 2) -/// would be added and the later triangle's connectivity would be changed -/// to (5,4,3). -/// By default, all old point's fields would be copied to the new point. -/// Use with caution. class VTKM_FILTER_GEOMETRY_REFINEMENT_EXPORT SplitSharpEdges : public vtkm::filter::FilterField { public: - VTKM_CONT - void SetFeatureAngle(vtkm::FloatDefault value) { this->FeatureAngle = value; } + /// @brief Specify the feature angle threshold to split on. + /// + /// The feature angle is the angle between the normals of the two polygons. Two polygons on + /// the same plane have a feature angle of 0. Perpendicular polygons have a feature angle + /// of 90 degrees. + /// + /// Any edge with a feature angle larger than this threshold will be split. The feature + /// angle is specified in degrees. The default value is 30 degrees. + VTKM_CONT void SetFeatureAngle(vtkm::FloatDefault value) { this->FeatureAngle = value; } - VTKM_CONT - vtkm::FloatDefault GetFeatureAngle() const { return this->FeatureAngle; } + /// @copydoc SetFeatureAngle + VTKM_CONT vtkm::FloatDefault GetFeatureAngle() const { return this->FeatureAngle; } private: VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override; diff --git a/vtkm/filter/geometry_refinement/Tetrahedralize.h b/vtkm/filter/geometry_refinement/Tetrahedralize.h index 96bf07a5d..124aa8246 100644 --- a/vtkm/filter/geometry_refinement/Tetrahedralize.h +++ b/vtkm/filter/geometry_refinement/Tetrahedralize.h @@ -20,10 +20,20 @@ namespace filter { namespace geometry_refinement { + +/// @brief Convert all polyhedra of a `vtkm::cont::DataSet` into tetrahedra. +/// +/// Note that although the tetrahedra will occupy the same space of the cells that +/// they replace, the interpolation of point fields within these cells might differ. +/// For example, the first order interpolation of a hexahedron uses trilinear +/// interpolation, which actually results in cubic equations. This differs from the +/// purely linear field in a tetrahedron, so the tetraheda replacement of the hexahedron +/// will not have exactly the same interpolation. class VTKM_FILTER_GEOMETRY_REFINEMENT_EXPORT Tetrahedralize : public vtkm::filter::Filter { VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override; }; + } // namespace geometry_refinement } // namespace filter } // namespace vtkm diff --git a/vtkm/filter/geometry_refinement/Triangulate.h b/vtkm/filter/geometry_refinement/Triangulate.h index 081bbcd58..b1987b3e0 100644 --- a/vtkm/filter/geometry_refinement/Triangulate.h +++ b/vtkm/filter/geometry_refinement/Triangulate.h @@ -20,10 +20,20 @@ namespace filter { namespace geometry_refinement { + +/// @brief Convert all polygons of a `vtkm::cont::DataSet` into triangles. +/// +/// Note that although the triangles will occupy the same space of the cells that +/// they replace, the interpolation of point fields within these cells might differ. +/// For example, the first order interpolation of a quadrilateral uses bilinear +/// interpolation, which actually results in quadratic equations. This differs from the +/// purely linear field in a triangle, so the triangle replacement of the quadrilateral +/// will not have exactly the same interpolation. class VTKM_FILTER_GEOMETRY_REFINEMENT_EXPORT Triangulate : public vtkm::filter::Filter { VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override; }; + } // namespace geometry_refinement } // namespace filter } // namespace vtkm diff --git a/vtkm/filter/geometry_refinement/Tube.h b/vtkm/filter/geometry_refinement/Tube.h index a9d510f04..61cd5dca1 100644 --- a/vtkm/filter/geometry_refinement/Tube.h +++ b/vtkm/filter/geometry_refinement/Tube.h @@ -20,29 +20,35 @@ namespace filter { namespace geometry_refinement { -/// \brief generate tube geometry from polylines. - -/// Takes as input a set of polylines, radius, num sides and capping flag. -/// Produces tubes along each polyline +/// @brief Generate a tube around each line and polyline. +/// +/// The radius, number of sides, and end capping can be specified for each tube. +/// The orientation of the geometry of the tube are computed automatically using +/// a heuristic to minimize the twisting along the input data set. +/// class VTKM_FILTER_GEOMETRY_REFINEMENT_EXPORT Tube : public vtkm::filter::FilterField { public: - VTKM_CONT - void SetRadius(vtkm::FloatDefault r) { this->Radius = r; } + /// @brief Specify the radius of each tube. + VTKM_CONT void SetRadius(vtkm::FloatDefault r) { this->Radius = r; } - VTKM_CONT - void SetNumberOfSides(vtkm::Id n) { this->NumberOfSides = n; } + /// @brief Specify the number of sides for each tube. + /// + /// The tubes are generated using a polygonal approximation. This option determines + /// how many facets will be generated around the tube. + VTKM_CONT void SetNumberOfSides(vtkm::Id n) { this->NumberOfSides = n; } - VTKM_CONT - void SetCapping(bool v) { this->Capping = v; } + /// The `Tube` filter can optionally add a cap at the ends of each tube. This option + /// specifies whether that cap is generated. + VTKM_CONT void SetCapping(bool v) { this->Capping = v; } private: VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override; vtkm::FloatDefault Radius{}; - vtkm::Id NumberOfSides{}; - bool Capping{}; + vtkm::Id NumberOfSides = 6; + bool Capping = false; }; } // namespace geometry_refinement } // namespace filter diff --git a/vtkm/filter/geometry_refinement/VertexClustering.h b/vtkm/filter/geometry_refinement/VertexClustering.h index dd681e366..fa8e4a88d 100644 --- a/vtkm/filter/geometry_refinement/VertexClustering.h +++ b/vtkm/filter/geometry_refinement/VertexClustering.h @@ -20,11 +20,11 @@ namespace filter { namespace geometry_refinement { -/// \brief Reduce the number of triangles in a mesh +/// \brief Reduce the number of triangles in a mesh. /// -/// VertexClustering is a filter to reduce the number of triangles in a +/// `VertexClustering` is a filter to reduce the number of triangles in a /// triangle mesh, forming a good approximation to the original geometry. The -/// input must be a dataset that only contains triangles. +/// input must be a `vtkm::cont::DataSet` that contains only triangles. /// /// The general approach of the algorithm is to cluster vertices in a uniform /// binning of space, accumulating to an average point within each bin. In @@ -45,17 +45,17 @@ namespace geometry_refinement /// doesn't increase the computation or memory of the algorithm and will produce /// significantly better results. /// -/// @warning -/// This filter currently doesn't propagate cell or point fields - class VTKM_FILTER_GEOMETRY_REFINEMENT_EXPORT VertexClustering : public vtkm::filter::Filter { public: - VTKM_CONT - void SetNumberOfDivisions(const vtkm::Id3& num) { this->NumberOfDivisions = num; } + /// @brief Specifies the dimensions of the uniform grid that establishes the bins used for clustering. + /// + /// Setting smaller numbers of dimensions produces a smaller output, but with a coarser + /// representation of the surface. + VTKM_CONT void SetNumberOfDivisions(const vtkm::Id3& num) { this->NumberOfDivisions = num; } - VTKM_CONT - const vtkm::Id3& GetNumberOfDivisions() const { return this->NumberOfDivisions; } + /// @copydoc SetNumberOfDivisions + VTKM_CONT const vtkm::Id3& GetNumberOfDivisions() const { return this->NumberOfDivisions; } private: VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override; diff --git a/vtkm/filter/mesh_info/GhostCellClassify.h b/vtkm/filter/mesh_info/GhostCellClassify.h index ca3027642..4d6f38a82 100644 --- a/vtkm/filter/mesh_info/GhostCellClassify.h +++ b/vtkm/filter/mesh_info/GhostCellClassify.h @@ -19,6 +19,16 @@ namespace filter { namespace mesh_info { + +/// @brief Determines which cells should be considered ghost cells in a structured data set. +/// +/// The ghost cells are expected to be on the border. The outer layer of cells are marked +/// as ghost cells and the remainder marked as normal. +/// +/// This filter generates a new cell-centered field marking the status of each cell. +/// Each entry is set to either `vtkm::CellClassification::Normal` or +/// `vtkm::CellClassification::Ghost`. +/// class VTKM_FILTER_MESH_INFO_EXPORT GhostCellClassify : public vtkm::filter::Filter { VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& inData) override; @@ -31,9 +41,15 @@ public: { } + /// @brief Set the name of the output field name. + /// + /// The output field is also marked as the ghost cell field in the output + /// `vtkm::cont::DataSet`. VTKM_CONT void SetGhostCellName(const std::string& fieldName) { this->GhostCellName = fieldName; } + /// @copydoc SetGhostCellName VTKM_CONT const std::string& GetGhostCellName() { return this->GhostCellName; } }; + } // namespace mesh_info } // namespace filter } // namespace vtkm diff --git a/vtkm/filter/multi_block/AmrArrays.h b/vtkm/filter/multi_block/AmrArrays.h index ab98b8e5c..44e299e70 100644 --- a/vtkm/filter/multi_block/AmrArrays.h +++ b/vtkm/filter/multi_block/AmrArrays.h @@ -21,6 +21,40 @@ namespace filter { namespace multi_block { + +/// @brief Generate arrays describing the AMR structure in a partitioned data set. +/// +/// AMR grids are represented by `vtkm::cont::PartitionedDataSet`, but this class +/// does not explicitly store the hierarchical structure of the mesh refinement. +/// This hierarchical arrangement needs to be captured in fields that describe +/// where blocks reside in the hierarchy. This filter analyses the arrangement +/// of partitions in a `vtkm::cont::PartitionedDataSet` and generates the following +/// field arrays. +/// +/// - `vtkAmrLevel` The AMR level at which the partition resides (with 0 being the +/// most coarse level). All the values for a particular partition are set to the +/// same value. +/// - `vtkAmrIndex` A unique identifier for each partition of a particular level. +/// Each partition of the same level will have a unique index, but the indices +/// will repeat across levels. All the values for a particular partition are set +/// to the same value. +/// - `vtkCompositeIndex` A unique identifier for each partition. This index is the +/// same as the index used for the partition in the containing +/// `vtkm::cont::PartitionedDataSet`. All the values for a particular partition are +/// set to the same value. +/// - `vtkGhostType` It is common for refinement levels in an AMR structure to +/// overlap more coarse grids. In this case, the overlapped coarse cells have +/// invalid data. The vtkGhostType field will track which cells are overlapped +/// and should be ignored. This array will have a 0 value for all valid cells and +/// a non-zero value for all invalid cells. (Specifically, if the bit specified by +/// `vtkm::CellClassification::BLANKED` is set, then the cell is overlapped with a +/// cell in a finer level.) +/// +/// These arrays are stored as cell fields in the partitions. +/// +/// This filter only operates on partitioned data sets where all the partitions +/// have cell sets of type `vtkm::cont::CellSetStructured`. This is characteristic +/// of AMR data sets. class VTKM_FILTER_MULTI_BLOCK_EXPORT AmrArrays : public vtkm::filter::Filter { private: @@ -69,6 +103,7 @@ private: /// contains all PartitonIds of the level below that have an overlap std::vector> ChildrenIdsVector; }; + } // namespace multi_block } // namesapce filter } // namespace vtkm diff --git a/vtkm/filter/resampling/HistSampling.cxx b/vtkm/filter/resampling/HistSampling.cxx index 561520225..bec784fb3 100644 --- a/vtkm/filter/resampling/HistSampling.cxx +++ b/vtkm/filter/resampling/HistSampling.cxx @@ -26,22 +26,22 @@ namespace resampling { namespace { -vtkm::cont::ArrayHandle CalculatPdf(vtkm::Id TotalPoints, - vtkm::FloatDefault SamplePercent, - vtkm::cont::ArrayHandle BinCount) +vtkm::cont::ArrayHandle CalculatPdf(vtkm::Id totalPoints, + vtkm::FloatDefault sampleFraction, + vtkm::cont::ArrayHandle binCount) { - vtkm::Id NumBins = BinCount.GetNumberOfValues(); + vtkm::Id NumBins = binCount.GetNumberOfValues(); vtkm::cont::ArrayHandleIndex indexArray(NumBins); vtkm::cont::ArrayHandle BinIndices; vtkm::cont::Algorithm::Copy(indexArray, BinIndices); - vtkm::cont::Algorithm::SortByKey(BinCount, BinIndices); + vtkm::cont::Algorithm::SortByKey(binCount, BinIndices); - vtkm::FloatDefault remainingSamples = SamplePercent * TotalPoints; + vtkm::FloatDefault remainingSamples = sampleFraction * totalPoints; vtkm::FloatDefault remainingBins = static_cast(NumBins); vtkm::cont::ArrayHandle targetSamples; targetSamples.Allocate(NumBins); - auto binCountPortal = BinCount.ReadPortal(); + auto binCountPortal = binCount.ReadPortal(); auto targetWritePortal = targetSamples.WritePortal(); for (int i = 0; i < NumBins; ++i) @@ -61,7 +61,7 @@ vtkm::cont::ArrayHandle CalculatPdf(vtkm::Id TotalPoints, invoker(vtkm::worklet::AcceptanceProbsWorklet{}, targetSamples, BinIndices, - BinCount, + binCount, acceptanceProbsVec); return acceptanceProbsVec; } @@ -78,10 +78,10 @@ vtkm::cont::DataSet HistSampling::DoExecute(const vtkm::cont::DataSet& input) vtkm::cont::ArrayHandle binCountArray; vtkm::cont::ArrayCopyShallowIfPossible( histogramOutput.GetField(histogram.GetOutputFieldName()).GetData(), binCountArray); - vtkm::Id TotalPoints = input.GetNumberOfPoints(); + vtkm::Id totalPoints = input.GetNumberOfPoints(); //computing pdf vtkm::cont::ArrayHandle probArray; - probArray = CalculatPdf(TotalPoints, this->SamplePercent, binCountArray); + probArray = CalculatPdf(totalPoints, this->SampleFraction, binCountArray); // use the acceptance probabilities and random array to create 0-1 array // generating random array between 0 to 1 vtkm::cont::ArrayHandle outputArray; diff --git a/vtkm/filter/resampling/HistSampling.h b/vtkm/filter/resampling/HistSampling.h index 1d037ab65..0658b05d9 100644 --- a/vtkm/filter/resampling/HistSampling.h +++ b/vtkm/filter/resampling/HistSampling.h @@ -13,37 +13,73 @@ #include #include +#include + namespace vtkm { namespace filter { namespace resampling { -// This filter can sample particles according to its importance level -// The source code of this filter comes from -// https://github.com/Alpine-DAV/ascent/blob/develop/src/libs/vtkh/filters/HistSampling.cpp -// More details can be found in the following paper: -// "In Situ Data-Driven Adaptive Sampling for Large-scale Simulation Data Summarization", -// Ayan Biswas, Soumya Dutta, Jesus Pulido, and James Ahrens, In Situ Infrastructures for Enabling Extreme-scale Analysis and Visualization (ISAV 2018), co-located with Supercomputing 2018 + +/// @brief Adaptively sample points to preserve tail features. +/// +/// This filter randomly samples the points of a `vtkm::cont::DataSet` and generates +/// a new `vtkm::cont::DataSet` with a subsampling of the points. The sampling is +/// adaptively selected to preserve tail and outlying features of the active field. +/// That is, the more rare a field value is, the more likely the point will be +/// selected in the sampling. This is done by creating a histogram of the field +/// and using that to derive the importance level of each field value. Details of +/// the algorithm can be found in the paper "In Situ Data-Driven Adaptive Sampling +/// for Large-scale Simulation Data Summarization" by Biswas, Dutta, Pulido, and Ahrens +/// as published in _In Situ Infrastructures for Enabling Extreme-scale Analysis and +/// Visualization_ (ISAV 2018). +/// +/// The cell set of the input data is removed and replaced with a set with a vertex +/// cell for each point. This effectively converts the data to a point cloud. class VTKM_FILTER_RESAMPLING_EXPORT HistSampling : public vtkm::filter::FilterField { public: + /// @brief Specify the number of bins used when computing the histogram. + /// + /// The histogram is used to select the importance of each field value. + /// More rare field values are more likely to be selected. VTKM_CONT void SetNumberOfBins(vtkm::Id numberOfBins) { this->NumberOfBins = numberOfBins; } + /// @copydoc SetNumberOfBins VTKM_CONT vtkm::Id GetNumberOfBins() { return this->NumberOfBins; } + + /// @brief Specify the fraction of points to create in the sampled data. + /// + /// A fraction of 1 means that all the points will be sampled and be in the output. + /// A fraction of 0 means that none of the points will be sampled. A fraction of 0.5 means + /// that half the points will be selected to be in the output. + VTKM_CONT void SetSampleFraction(vtkm::FloatDefault fraction) { this->SampleFraction = fraction; } + /// @copydoc SetSampleFraction + VTKM_CONT vtkm::FloatDefault GetSampleFraction() const { return this->SampleFraction; } + + VTKM_DEPRECATED(2.2, "Use SetSampleFraction().") VTKM_CONT void SetSamplePercent(vtkm::FloatDefault samplePercent) { - this->SamplePercent = samplePercent; + this->SetSampleFraction(samplePercent); } - VTKM_CONT vtkm::FloatDefault GetSamplePercent() { return this->SamplePercent; } - VTKM_CONT vtkm::UInt32 GetSeed() { return this->Seed; } + VTKM_DEPRECATED(2.2, "Use GetSampleFraction().") + VTKM_CONT vtkm::FloatDefault GetSamplePercent() const { return this->GetSampleFraction(); } + + /// @brief Specify the seed used for random number generation. + /// + /// The random numbers are used to select which points to pull from the input. If + /// the same seed is used for multiple invocations, the results will be the same. VTKM_CONT void SetSeed(vtkm::UInt32 seed) { this->Seed = seed; } + /// @copydoc SetSeed + VTKM_CONT vtkm::UInt32 GetSeed() { return this->Seed; } private: VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override; - vtkm::Id NumberOfBins; - vtkm::FloatDefault SamplePercent = static_cast(0.1); + vtkm::Id NumberOfBins = 10; + vtkm::FloatDefault SampleFraction = 0.1f; vtkm::UInt32 Seed = 0; }; + } // namespace resampling } // namespace filter } // namespace vtkm diff --git a/vtkm/filter/resampling/Probe.h b/vtkm/filter/resampling/Probe.h index 56a4fbf3d..813eabd49 100644 --- a/vtkm/filter/resampling/Probe.h +++ b/vtkm/filter/resampling/Probe.h @@ -19,20 +19,43 @@ namespace filter { namespace resampling { + +/// @brief Sample the fields of a data set at specified locations. +/// +/// The `vtkm::filter::resampling::Probe` filter samples the fields of one +/// `vtkm::cont::DataSet` and places them in the fields of another +/// `vtkm::cont::DataSet`. +/// +/// To use this filter, first specify a geometry to probe with with `SetGeometry()`. +/// The most important feature of this geometry is its coordinate system. +/// When you call `Execute()`, the output will be the data specified with +/// `SetGeometry()` but will have the fields of the input to `Execute()` +/// transferred to it. The fields are transfered by probing the input data +/// set at the point locations of the geometry. +/// class VTKM_FILTER_RESAMPLING_EXPORT Probe : public vtkm::filter::FilterField { public: - VTKM_CONT - void SetGeometry(const vtkm::cont::DataSet& geometry) + /// @brief Specify the geometry to probe with. + /// + /// When `Execute()` is called, the input data will be probed at all the point + /// locations of this @p geometry as specified by its coordinate system. + VTKM_CONT void SetGeometry(const vtkm::cont::DataSet& geometry) { this->Geometry = vtkm::cont::DataSet(); this->Geometry.CopyStructure(geometry); } - VTKM_CONT - const vtkm::cont::DataSet& GetGeometry() const { return this->Geometry; } + /// @copydoc SetGeometry + VTKM_CONT const vtkm::cont::DataSet& GetGeometry() const { return this->Geometry; } + /// @brief Specify the value to use for points outside the bounds of the input. + /// + /// It is possible that the sampling geometry will have points outside the bounds of + /// the input. When this happens, the field will be set to this "invalid" value. + /// By default, the invalid value is NaN. VTKM_CONT void SetInvalidValue(vtkm::Float64 invalidValue) { this->InvalidValue = invalidValue; } + /// @copydoc SetInvalidValue VTKM_CONT vtkm::Float64 GetInvalidValue() const { return this->InvalidValue; } private: @@ -42,6 +65,7 @@ private: vtkm::Float64 InvalidValue = vtkm::Nan64(); }; + } // namespace resampling } // namespace filter } // namespace vtkm diff --git a/vtkm/filter/scalar_topology/worklet/contourtree_augmented/DataSetMesh.h b/vtkm/filter/scalar_topology/worklet/contourtree_augmented/DataSetMesh.h index 355bb6825..440c2fbd0 100644 --- a/vtkm/filter/scalar_topology/worklet/contourtree_augmented/DataSetMesh.h +++ b/vtkm/filter/scalar_topology/worklet/contourtree_augmented/DataSetMesh.h @@ -150,7 +150,7 @@ public: /// Routine to return the global IDs for a set of vertices /// We here return a fancy array handle to convert values on-the-fly without requiring additional memory - /// @param[in] meshIds Array with sort Ids to be converted from local to global Ids + /// @param[in] sortIds Array with sort Ids to be converted from local to global Ids /// @param[in] localToGlobalIdRelabeler This parameter is the IdRelabeler /// used to transform local to global Ids. The relabeler relies on the /// decomposition of the global mesh which is not know by this block. @@ -189,7 +189,7 @@ public: protected: //TODO/FIXME: Update comment, possibly refactor and move somewhere else (helper function outside class?) ///Compute a list of the global Iss of all vertices that logically belong to the data block represented by this - ///mesh object (used in distributd parallel computation). This is needed to avoid multiple counting on bousndaries + ///mesh object (used in distributed parallel computation). This is needed to avoid multiple counting on boundaries ///in the hierarchy during distributed parallel contour tree computation. /// Implementation of GetOwnedVerticesByGlobalId used internally by derived classes to /// implement the specific variant of the function .The implementations vary based on the @@ -199,6 +199,9 @@ protected: /// and as such have PrepareForExecution functions that return a MeshBoundary object that /// we can use here. We are passing in the mesh since the base DataSetMesh class does /// not know about MeshBoundary classes and so we are passing the mesh in. + /// @param[in] localToGlobalIdRelabeler This parameter is the IdRelabeler + /// used to transform local to global Ids. The relabeler relies on the + /// decomposition of the global mesh which is not know by this block. /// @param[out] ownedVertices List of vertices that logically belong to template void GetOwnedVerticesByGlobalIdImpl( diff --git a/vtkm/filter/scalar_topology/worklet/contourtree_augmented/Types.h b/vtkm/filter/scalar_topology/worklet/contourtree_augmented/Types.h index 3cd8fc77f..e1d02f68b 100644 --- a/vtkm/filter/scalar_topology/worklet/contourtree_augmented/Types.h +++ b/vtkm/filter/scalar_topology/worklet/contourtree_augmented/Types.h @@ -329,9 +329,10 @@ public: struct GetPointDimensions { ///@{ - /// Get the number of rows, cols, and slices of a vtkm::cont::CellSetStructured - /// @param[in] cells The input vtkm::cont::CellSetStructured - /// @param[out] pointDimensions mesh size (#cols, #rows #slices in old notation) with last dimension having a value of 1 for 2D data + /// Get the number of rows, cols, and slices of a vtkm::cont::CellSetStructured. + /// @param[in] cells The input vtkm::cont::CellSetStructured. + /// @param[out] pointDimensions mesh size (often referred to as columns, rows, and slices) + /// with last dimension having a value of 1 for 2D data. void operator()(const vtkm::cont::CellSetStructured<2>& cells, vtkm::Id3& pointDimensions) const { vtkm::Id2 pointDimensions2D = cells.GetPointDimensions(); diff --git a/vtkm/filter/scalar_topology/worklet/contourtree_distributed/ComputeDistributedContourTreeFunctor.h b/vtkm/filter/scalar_topology/worklet/contourtree_distributed/ComputeDistributedContourTreeFunctor.h index a5d0f6e58..446cb8617 100644 --- a/vtkm/filter/scalar_topology/worklet/contourtree_distributed/ComputeDistributedContourTreeFunctor.h +++ b/vtkm/filter/scalar_topology/worklet/contourtree_distributed/ComputeDistributedContourTreeFunctor.h @@ -80,11 +80,12 @@ class ComputeDistributedContourTreeFunctor { public: /// Create the functor - /// @param[in] globalSize Global extends of the input mesh (i.e., number of mesh points in each dimension) + /// @param[in] globalSize Global extents of the input mesh (i.e., number of mesh points in each dimension). + /// @param[in] useBoundaryExtremaOnly Use boundary extrema only (instead of the full boundary) during the fan in. /// @param[in] timingsLogLevel Set the vtkm::cont:LogLevel to be used to record timings information - /// specific to the computation of the hierachical contour tree + /// specific to the computation of the hierachical contour tree. /// @param[in] treeLogLevel Set the vtkm::cont:LogLevel to be used to record metadata information - /// about the various trees computed as part of the hierarchical contour tree compute + /// about the various trees computed as part of the hierarchical contour tree compute. ComputeDistributedContourTreeFunctor( vtkm::Id3 globalSize, bool useBoundaryExtremaOnly, diff --git a/vtkm/filter/scalar_topology/worklet/contourtree_distributed/HierarchicalHyperSweeper.h b/vtkm/filter/scalar_topology/worklet/contourtree_distributed/HierarchicalHyperSweeper.h index 0cd0fa343..da7126a9b 100644 --- a/vtkm/filter/scalar_topology/worklet/contourtree_distributed/HierarchicalHyperSweeper.h +++ b/vtkm/filter/scalar_topology/worklet/contourtree_distributed/HierarchicalHyperSweeper.h @@ -136,7 +136,6 @@ public: /// Constructor /// @param[in] blockId The Id of the base block (used for debug output) /// @param[in] hierarchicalTree the tree that to hypersweeps over - /// @param[in] baseBlock the underlying mesh base block type /// @param[in] intrinsicValues array of values of intrinisic nodes are just being stored here but not modified /// @param[in] dependentValues array of values being operated over (same size as supernode set) HierarchicalHyperSweeper( diff --git a/vtkm/filter/scalar_topology/worklet/contourtree_distributed/tree_grafter/CopyNewSupernodesSetSuperchildrenWorklet.h b/vtkm/filter/scalar_topology/worklet/contourtree_distributed/tree_grafter/CopyNewSupernodesSetSuperchildrenWorklet.h index 73f386ed5..975c298dd 100644 --- a/vtkm/filter/scalar_topology/worklet/contourtree_distributed/tree_grafter/CopyNewSupernodesSetSuperchildrenWorklet.h +++ b/vtkm/filter/scalar_topology/worklet/contourtree_distributed/tree_grafter/CopyNewSupernodesSetSuperchildrenWorklet.h @@ -83,7 +83,7 @@ public: using InputDomain = _1; /// Default Constructor - /// @param[in]numhierarchicalTreeSupernodes should be set to hierarchicalTree.Supernodes.GetNumberOfValues() + /// @param[in] numHierarchicalTreeSupernodes should be set to hierarchicalTree.Supernodes.GetNumberOfValues() VTKM_EXEC_CONT CopyNewSupernodesSetSuperchildrenWorklet(vtkm::Id numHierarchicalTreeSupernodes) : NumHierarchicalTreeSupernodes(numHierarchicalTreeSupernodes) diff --git a/vtkm/filter/vector_analysis/CrossProduct.h b/vtkm/filter/vector_analysis/CrossProduct.h index 06dcbbb14..e203ff23e 100644 --- a/vtkm/filter/vector_analysis/CrossProduct.h +++ b/vtkm/filter/vector_analysis/CrossProduct.h @@ -22,101 +22,97 @@ namespace filter namespace vector_analysis { +/// @brief Compute the cross product of 3D vector fields. +/// +/// The left part of the operand is the "primary" field and the right part of the operand +/// is the "secondary" field. class VTKM_FILTER_VECTOR_ANALYSIS_EXPORT CrossProduct : public vtkm::filter::FilterField { public: VTKM_CONT CrossProduct(); - ///@{ - /// Choose the primary field to operate on. In the cross product operation A x B, A is - /// the primary field. - VTKM_CONT - void SetPrimaryField( + /// @brief Specify the primary field to operate on. + /// + /// In the cross product operation A x B, A is the primary field. + /// + /// The primary field is an alias for active field index 0. As with any active field, + /// it can be set as a named field or as a coordinate system. + VTKM_CONT void SetPrimaryField( const std::string& name, vtkm::cont::Field::Association association = vtkm::cont::Field::Association::Any) { this->SetActiveField(name, association); } + /// @copydoc SetPrimaryField VTKM_CONT const std::string& GetPrimaryFieldName() const { return this->GetActiveFieldName(); } + /// @copydoc SetPrimaryField VTKM_CONT vtkm::cont::Field::Association GetPrimaryFieldAssociation() const { return this->GetActiveFieldAssociation(); } - ///@} - ///@{ - /// When set to true, uses a coordinate system as the primary field instead of the one selected - /// by name. Use SetPrimaryCoordinateSystem to select which coordinate system. - VTKM_CONT - void SetUseCoordinateSystemAsPrimaryField(bool flag) + /// @copydoc SetPrimaryField + VTKM_CONT void SetUseCoordinateSystemAsPrimaryField(bool flag) { this->SetUseCoordinateSystemAsField(flag); } - VTKM_CONT - bool GetUseCoordinateSystemAsPrimaryField() const + /// @copydoc SetPrimaryField + VTKM_CONT bool GetUseCoordinateSystemAsPrimaryField() const { return this->GetUseCoordinateSystemAsField(); } - ///@} - ///@{ - /// Select the coordinate system index to use as the primary field. This only has an effect when - /// UseCoordinateSystemAsPrimaryField is true. + /// @copydoc SetPrimaryField VTKM_CONT void SetPrimaryCoordinateSystem(vtkm::Id index) { this->SetActiveCoordinateSystem(index); } - VTKM_CONT - vtkm::Id GetPrimaryCoordinateSystemIndex() const + VTKM_CONT vtkm::Id GetPrimaryCoordinateSystemIndex() const { return this->GetActiveCoordinateSystemIndex(); } - ///@} - ///@{ - /// Choose the secondary field to operate on. In the dot product operation A . B, B is - /// the secondary field. - VTKM_CONT - void SetSecondaryField( + /// @brief Specify the secondary field to operate on. + /// + /// In the cross product operation A x B, B is the secondary field. + /// + /// The secondary field is an alias for the active field index 1. As with any active field, + /// it can be set as a named field or as a coordinate system. + VTKM_CONT void SetSecondaryField( const std::string& name, vtkm::cont::Field::Association association = vtkm::cont::Field::Association::Any) { this->SetActiveField(1, name, association); } - VTKM_CONT const std::string& GetSecondaryFieldName() const { return this->GetActiveFieldName(1); } + /// @copydoc SetSecondaryField + VTKM_CONT + const std::string& GetSecondaryFieldName() const { return this->GetActiveFieldName(1); } + /// @copydoc SetSecondaryField VTKM_CONT vtkm::cont::Field::Association GetSecondaryFieldAssociation() const { return this->GetActiveFieldAssociation(1); } - ///@} - ///@{ - /// When set to true, uses a coordinate system as the secondary field instead of the one selected - /// by name. Use SetSecondaryCoordinateSystem to select which coordinate system. - VTKM_CONT - void SetUseCoordinateSystemAsSecondaryField(bool flag) + /// @copydoc SetSecondaryField + VTKM_CONT void SetUseCoordinateSystemAsSecondaryField(bool flag) { this->SetUseCoordinateSystemAsField(1, flag); } - VTKM_CONT - bool GetUseCoordinateSystemAsSecondaryField() const + /// @copydoc SetSecondaryField + VTKM_CONT bool GetUseCoordinateSystemAsSecondaryField() const { return this->GetUseCoordinateSystemAsField(1); } - ///@} - ///@{ - /// Select the coordinate system index to use as the secondary field. This only has an effect when - /// UseCoordinateSystemAsSecondaryField is true. + /// @copydoc SetSecondaryField VTKM_CONT void SetSecondaryCoordinateSystem(vtkm::Id index) { this->SetActiveCoordinateSystem(1, index); } - VTKM_CONT - vtkm::Id GetSecondaryCoordinateSystemIndex() const + /// @copydoc SetSecondaryField + VTKM_CONT vtkm::Id GetSecondaryCoordinateSystemIndex() const { return this->GetActiveCoordinateSystemIndex(1); } - ///@} private: VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override; diff --git a/vtkm/filter/vector_analysis/DotProduct.h b/vtkm/filter/vector_analysis/DotProduct.h index 6ba535969..e555f40bc 100644 --- a/vtkm/filter/vector_analysis/DotProduct.h +++ b/vtkm/filter/vector_analysis/DotProduct.h @@ -20,106 +20,109 @@ namespace filter { namespace vector_analysis { + +/// @brief Compute the dot product of vector fields. +/// +/// The left part of the operand is the "primary" field and the right part of the operand +/// is the "secondary" field (although the dot product is commutative, so the order of +/// primary and secondary seldom matters). +/// +/// The dot product can operate on vectors of any length. class VTKM_FILTER_VECTOR_ANALYSIS_EXPORT DotProduct : public vtkm::filter::FilterField { public: VTKM_CONT DotProduct(); - ///@{ - /// Choose the primary field to operate on. In the dot product operation A . B, A is - /// the primary field. - VTKM_CONT - void SetPrimaryField( + /// @brief Specify the primary field to operate on. + /// + /// In the dot product operation A . B, A is the primary field. + /// + /// The primary field is an alias for active field index 0. As with any active field, + /// it can be set as a named field or as a coordinate system. + VTKM_CONT void SetPrimaryField( const std::string& name, vtkm::cont::Field::Association association = vtkm::cont::Field::Association::Any) { this->SetActiveField(name, association); } + /// @copydoc SetPrimaryField VTKM_CONT const std::string& GetPrimaryFieldName() const { return this->GetActiveFieldName(); } + /// @copydoc SetPrimaryField VTKM_CONT vtkm::cont::Field::Association GetPrimaryFieldAssociation() const { return this->GetActiveFieldAssociation(); } - ///@{ - /// When set to true, uses a coordinate system as the primary field instead of the one selected - /// by name. Use SetPrimaryCoordinateSystem to select which coordinate system. - VTKM_CONT - void SetUseCoordinateSystemAsPrimaryField(bool flag) + /// @copydoc SetPrimaryField + VTKM_CONT void SetUseCoordinateSystemAsPrimaryField(bool flag) { this->SetUseCoordinateSystemAsField(flag); } - VTKM_CONT - bool GetUseCoordinateSystemAsPrimaryField() const + /// @copydoc SetPrimaryField + VTKM_CONT bool GetUseCoordinateSystemAsPrimaryField() const { return this->GetUseCoordinateSystemAsField(); } - ///@} - ///@{ - /// Select the coordinate system coord_idx to use as the primary field. This only has an effect when - /// UseCoordinateSystemAsPrimaryField is true. - VTKM_CONT - void SetPrimaryCoordinateSystem(vtkm::Id coord_idx) + /// @copydoc SetPrimaryField + VTKM_CONT void SetPrimaryCoordinateSystem(vtkm::Id coord_idx) { this->SetActiveCoordinateSystem(coord_idx); } - VTKM_CONT - vtkm::Id GetPrimaryCoordinateSystemIndex() const + /// @copydoc SetPrimaryField + VTKM_CONT vtkm::Id GetPrimaryCoordinateSystemIndex() const { return this->GetActiveCoordinateSystemIndex(); } - ///@} - ///@{ - /// Choose the secondary field to operate on. In the dot product operation A . B, B is - /// the secondary field. - VTKM_CONT - void SetSecondaryField( + /// @brief Specify the secondary field to operate on. + /// + /// In the dot product operation A . B, B is the secondary field. + /// + /// The secondary field is an alias for active field index 1. As with any active field, + /// it can be set as a named field or as a coordinate system. + VTKM_CONT void SetSecondaryField( const std::string& name, vtkm::cont::Field::Association association = vtkm::cont::Field::Association::Any) { this->SetActiveField(1, name, association); } + /// @copydoc SetSecondaryField VTKM_CONT const std::string& GetSecondaryFieldName() const { return this->GetActiveFieldName(1); } + /// @copydoc SetSecondaryField VTKM_CONT vtkm::cont::Field::Association GetSecondaryFieldAssociation() const { return this->GetActiveFieldAssociation(1); } - ///@} - ///@{ - /// When set to true, uses a coordinate system as the secondary field instead of the one selected - /// by name. Use SetSecondaryCoordinateSystem to select which coordinate system. - VTKM_CONT - void SetUseCoordinateSystemAsSecondaryField(bool flag) + /// @copydoc SetSecondaryField + VTKM_CONT void SetUseCoordinateSystemAsSecondaryField(bool flag) { this->SetUseCoordinateSystemAsField(1, flag); } - VTKM_CONT - bool GetUseCoordinateSystemAsSecondaryField() const + /// @copydoc SetSecondaryField + VTKM_CONT bool GetUseCoordinateSystemAsSecondaryField() const { return this->GetUseCoordinateSystemAsField(1); } - ///@} - ///@{ - /// Select the coordinate system index to use as the secondary field. This only has an effect when - /// UseCoordinateSystemAsSecondaryField is true. - VTKM_CONT - void SetSecondaryCoordinateSystem(vtkm::Id index) { this->SetActiveCoordinateSystem(1, index); } - VTKM_CONT - vtkm::Id GetSecondaryCoordinateSystemIndex() const + /// @copydoc SetSecondaryField + VTKM_CONT void SetSecondaryCoordinateSystem(vtkm::Id index) + { + this->SetActiveCoordinateSystem(1, index); + } + /// @copydoc SetSecondaryField + VTKM_CONT vtkm::Id GetSecondaryCoordinateSystemIndex() const { return this->GetActiveCoordinateSystemIndex(1); } - ///@} private: vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override; }; + } // namespace vector_analysis } // namespace filter } // namespace vtkm diff --git a/vtkm/filter/vector_analysis/Gradient.h b/vtkm/filter/vector_analysis/Gradient.h index e2231b375..fe792210e 100644 --- a/vtkm/filter/vector_analysis/Gradient.h +++ b/vtkm/filter/vector_analysis/Gradient.h @@ -20,73 +20,86 @@ namespace filter { namespace vector_analysis { -/// \brief A general filter for gradient estimation. + +/// @brief A general filter for gradient estimation. +/// /// Estimates the gradient of a point field in a data set. The created gradient array /// can be determined at either each point location or at the center of each cell. /// /// The default for the filter is output as cell centered gradients. -/// To enable point based gradient computation enable \c SetComputePointGradient +/// To enable point based gradient computation enable `SetComputePointGradient()` /// -/// Note: If no explicit name for the output field is provided the filter will +/// If no explicit name for the output field is provided the filter will /// default to "Gradients" class VTKM_FILTER_VECTOR_ANALYSIS_EXPORT Gradient : public vtkm::filter::FilterField { public: + /// @brief Specify whether to compute gradients + /// /// When this flag is on (default is off), the gradient filter will provide a /// point based gradients, which are significantly more costly since for each /// point we need to compute the gradient of each cell that uses it. void SetComputePointGradient(bool enable) { ComputePointGradient = enable; } + /// @copydoc SetComputePointGradient bool GetComputePointGradient() const { return ComputePointGradient; } - /// Add divergence field to the output data. The name of the array - /// will be Divergence and will be a cell field unless \c ComputePointGradient - /// is enabled. The input array must have 3 components in order to - /// compute this. The default is off. + /// Add divergence field to the output data. The input array must have 3 components + /// to compute this. The default is off. void SetComputeDivergence(bool enable) { ComputeDivergence = enable; } + /// @copydoc SetComputeDivergence bool GetComputeDivergence() const { return ComputeDivergence; } - /// Add voriticity/curl field to the output data. The name of the array - /// will be Vorticity and will be a cell field unless \c ComputePointGradient - /// is enabled. The input array must have 3 components in order to - /// compute this. The default is off. + /// When `SetComputeDivergence()` is enabled, the result is stored in a field + /// of this name. If not specified, the name of the field will be `Divergence`. + void SetDivergenceName(const std::string& name) { this->DivergenceName = name; } + /// @copydoc SetDivergenceName + const std::string& GetDivergenceName() const { return this->DivergenceName; } + + /// Add voriticity/curl field to the output data. The input array must have 3 components + /// to compute this. The default is off. void SetComputeVorticity(bool enable) { ComputeVorticity = enable; } + /// @copydoc SetComputeVorticity bool GetComputeVorticity() const { return ComputeVorticity; } - /// Add Q-criterion field to the output data. The name of the array - /// will be QCriterion and will be a cell field unless \c ComputePointGradient - /// is enabled. The input array must have 3 components in order to - /// compute this. The default is off. + /// When `SetComputeVorticity()` is enabled, the result is stored in a field + /// of this name. If not specified, the name of the field will be `Vorticity`. + void SetVorticityName(const std::string& name) { this->VorticityName = name; } + /// @copydoc SetVorticityName + const std::string& GetVorticityName() const { return this->VorticityName; } + + /// Add Q-criterion field to the output data. The input array must have 3 components + /// to compute this. The default is off. void SetComputeQCriterion(bool enable) { ComputeQCriterion = enable; } + /// @copydoc SetComputeQCriterion bool GetComputeQCriterion() const { return ComputeQCriterion; } + /// When `SetComputeQCriterion()` is enabled, the result is stored in a field + /// of this name. If not specified, the name of the field will be `QCriterion`. + void SetQCriterionName(const std::string& name) { this->QCriterionName = name; } + /// @copydoc SetQCriterionName + const std::string& GetQCriterionName() const { return this->QCriterionName; } + /// Add gradient field to the output data. The name of the array - /// will be Gradients and will be a cell field unless \c ComputePointGradient + /// will be `Gradients` unless otherwise specified with `SetOutputFieldName` + /// and will be a cell field unless `ComputePointGradient()` /// is enabled. It is useful to turn this off when you are only interested /// in the results of Divergence, Vorticity, or QCriterion. The default is on. void SetComputeGradient(bool enable) { StoreGradient = enable; } + /// @copydoc SetComputeGradient bool GetComputeGradient() const { return StoreGradient; } /// Make the vector gradient output format be in FORTRAN Column-major order. - /// This is only used when the input field is a vector field ( 3 components ). - /// Enabling column-major is important if integrating with other projects + /// This is only used when the input field is a vector field. + /// Enabling column-major is important if integrating with other projects /// such as VTK. - /// Default: Row Order + /// Default: Row Order. void SetColumnMajorOrdering() { RowOrdering = false; } /// Make the vector gradient output format be in C Row-major order. - /// This is only used when the input field is a vector field ( 3 components ). - /// Default: Row Order + /// This is only used when the input field is a vector field. + /// Default: Row Order. void SetRowMajorOrdering() { RowOrdering = true; } - void SetDivergenceName(const std::string& name) { this->DivergenceName = name; } - const std::string& GetDivergenceName() const { return this->DivergenceName; } - - void SetVorticityName(const std::string& name) { this->VorticityName = name; } - const std::string& GetVorticityName() const { return this->VorticityName; } - - void SetQCriterionName(const std::string& name) { this->QCriterionName = name; } - const std::string& GetQCriterionName() const { return this->QCriterionName; } - private: vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& inputDataSet) override; diff --git a/vtkm/filter/vector_analysis/SurfaceNormals.h b/vtkm/filter/vector_analysis/SurfaceNormals.h index 6042552bb..989912bb7 100644 --- a/vtkm/filter/vector_analysis/SurfaceNormals.h +++ b/vtkm/filter/vector_analysis/SurfaceNormals.h @@ -19,12 +19,28 @@ namespace filter { namespace vector_analysis { -/// \brief compute normals for polygonal mesh +/// \brief Computes normals for polygonal mesh. /// -/// Compute surface normals on points and/or cells of a polygonal dataset. +/// This filter computes surface normals on points and/or cells of a polygonal dataset. /// The cell normals are faceted and are computed based on the plane where a /// face lies. The point normals are smooth normals, computed by averaging -/// the face normals of incident cells. +/// the face normals of incident cells. The normals will be consistently oriented to +/// point in the direction of the same connected surface if possible. +/// +/// The point and cell normals may be oriented to a point outside of the manifold surface +/// by turning on the auto orient normals option (`SetAutoOrientNormals()`), or they may +/// point inward by also setting flip normals (`SetFlipNormals()`) to true. +/// +/// Triangle vertices will be reordered to be wound counter-clockwise around the cell +/// normals when the consistency option (`SetConsistency()`) is enabled. +/// +/// For non-polygonal cells, a zeroed vector is assigned. The point normals are computed +/// by averaging the cell normals of the incident cells of each point. +/// +/// The default name for the output fields is `Normals`, but that can be overridden using +/// the `SetCellNormalsName()` and `SetPointNormalsName()` methods. The filter will also +/// respect the name in `SetOutputFieldName()` if neither of the others are set. +/// class VTKM_FILTER_VECTOR_ANALYSIS_EXPORT SurfaceNormals : public vtkm::filter::FilterField { public: @@ -33,66 +49,73 @@ public: /// use-case for surface normals. SurfaceNormals(); - /// Set/Get if cell normals should be generated. Default is off. - /// @{ + /// @brief Specify whether cell normals should be generated. + /// + /// Default is off. void SetGenerateCellNormals(bool value) { this->GenerateCellNormals = value; } + /// @copydoc SetGenerateCellNormals bool GetGenerateCellNormals() const { return this->GenerateCellNormals; } - /// @} - /// Set/Get if the cell normals should be normalized. Default value is true. + /// @brief Specify whether the cell normals should be normalized. + /// + /// Default value is true. /// The intended use case of this flag is for faster, approximate point /// normals generation by skipping the normalization of the face normals. /// Note that when set to false, the result cell normals will not be unit /// length normals and the point normals will be different. - /// @{ void SetNormalizeCellNormals(bool value) { this->NormalizeCellNormals = value; } + /// @copydoc SetNormalizeCellNormals bool GetNormalizeCellNormals() const { return this->NormalizeCellNormals; } - /// @} - /// Set/Get if the point normals should be generated. Default is on. - /// @{ + /// @brief Specify whether the point normals should be generated. + /// + /// Default is on. void SetGeneratePointNormals(bool value) { this->GeneratePointNormals = value; } + /// @copydoc SetGeneratePointNormals bool GetGeneratePointNormals() const { return this->GeneratePointNormals; } - /// @} - /// Set/Get the name of the cell normals field. Default is "Normals". - /// @{ + /// @brief Specify the name of the cell normals field. + /// + /// Default is `Normals`. void SetCellNormalsName(const std::string& name) { this->CellNormalsName = name; } + /// @copydoc SetCellNormalsName const std::string& GetCellNormalsName() const { return this->CellNormalsName; } - /// @} - /// Set/Get the name of the point normals field. Default is "Normals". - /// @{ + /// @brief Specify the name of the point normals field. + /// + /// Default is `Normals`. void SetPointNormalsName(const std::string& name) { this->PointNormalsName = name; } + /// @copydoc SetPointNormalsName const std::string& GetPointNormalsName() const { return this->PointNormalsName; } - /// @} - /// If true, the normals will be oriented to face outwards from the surface. + /// @brief Specify whether to orient the normals outwards from the surface. + /// /// This requires a closed manifold surface or the behavior is undefined. - /// This option is expensive but necessary for rendering. + /// This option is expensive but might be necessary for rendering. /// To make the normals point inward, set FlipNormals to true. /// Default is off. - /// @{ void SetAutoOrientNormals(bool v) { this->AutoOrientNormals = v; } + /// @copydoc SetAutoOrientNormals bool GetAutoOrientNormals() const { return this->AutoOrientNormals; } - /// @} - /// Reverse the normals to point inward when AutoOrientNormals is true. - /// Default is false. - /// @{ + /// @brief Specify the direction to point normals when `SetAutoOrientNormals()` is true. + /// + /// When this flag is false (the default), the normals will be oriented to point outward. + /// When the flag is true, the normals will point inward. + /// This option has no effect if auto orient normals is off. void SetFlipNormals(bool v) { this->FlipNormals = v; } + /// @copydoc SetFlipNormals bool GetFlipNormals() const { return this->FlipNormals; } - /// @} - /// Ensure that polygon winding is consistent with normal orientation. + /// @brief Specify whtehr polygon winding should be made consistent with normal orientation. + /// /// Triangles are wound such that their points are counter-clockwise around /// the generated cell normal. Default is true. - /// @note This currently only affects triangles. - /// @note This is only applied when cell normals are generated. - /// @{ + /// This currently only affects triangles. + /// This is only applied when cell normals are generated. void SetConsistency(bool v) { this->Consistency = v; } + /// @copydoc SetConsistency bool GetConsistency() const { return this->Consistency; } - /// @} private: VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& inputDataSet) override; diff --git a/vtkm/filter/vector_analysis/VectorMagnitude.h b/vtkm/filter/vector_analysis/VectorMagnitude.h index eb19c5974..d178f65a0 100644 --- a/vtkm/filter/vector_analysis/VectorMagnitude.h +++ b/vtkm/filter/vector_analysis/VectorMagnitude.h @@ -20,6 +20,13 @@ namespace filter { namespace vector_analysis { + +/// @brief Compute the magnitudes of a vector field. +/// +/// The vector field is selected with the `SetActiveField()` method. The default +/// name for the output field is ``magnitude``, but that can be overridden using +/// the `SetOutputFieldName()` method. +/// class VTKM_FILTER_VECTOR_ANALYSIS_EXPORT VectorMagnitude : public vtkm::filter::FilterField { public: @@ -28,6 +35,7 @@ public: private: VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override; }; + } // namespace vector_analysis } // namespace filter } // namespace vtkm::filter diff --git a/vtkm/filter/zfp/ZFPCompressor1D.h b/vtkm/filter/zfp/ZFPCompressor1D.h index 39c5ed0b2..fb0c4f61f 100644 --- a/vtkm/filter/zfp/ZFPCompressor1D.h +++ b/vtkm/filter/zfp/ZFPCompressor1D.h @@ -20,16 +20,19 @@ namespace filter { namespace zfp { -/// \brief Compress a scalar field using ZFP -/// Takes as input a 1D array and generates on +/// \brief Compress a scalar field using ZFP. +/// +/// Takes as input a 1D array and generates an /// output of compressed data. /// @warning -/// This filter is currently only supports 1D volumes. +/// This filter currently only supports 1D structured cell sets. class VTKM_FILTER_ZFP_EXPORT ZFPCompressor1D : public vtkm::filter::FilterField { public: + /// @brief Specifies the rate of compression. void SetRate(vtkm::Float64 _rate) { rate = _rate; } + /// @copydoc SetRate vtkm::Float64 GetRate() { return rate; } private: @@ -37,6 +40,7 @@ private: vtkm::Float64 rate = 0; }; + } // namespace zfp } // namespace filter } // namespace vtkm::filter diff --git a/vtkm/filter/zfp/ZFPCompressor2D.h b/vtkm/filter/zfp/ZFPCompressor2D.h index e48fcb404..964853b52 100644 --- a/vtkm/filter/zfp/ZFPCompressor2D.h +++ b/vtkm/filter/zfp/ZFPCompressor2D.h @@ -20,16 +20,19 @@ namespace filter { namespace zfp { -/// \brief Compress a scalar field using ZFP -/// Takes as input a 1D array and generates on +/// \brief Compress a scalar field using ZFP. +/// +/// Takes as input a 2D array and generates an /// output of compressed data. /// @warning -/// This filter is currently only supports 1D volumes. +/// This filter is currently only supports 2D structured cell sets. class VTKM_FILTER_ZFP_EXPORT ZFPCompressor2D : public vtkm::filter::FilterField { public: + /// @brief Specifies the rate of compression. void SetRate(vtkm::Float64 _rate) { rate = _rate; } + /// @copydoc SetRate vtkm::Float64 GetRate() { return rate; } private: @@ -37,6 +40,7 @@ private: vtkm::Float64 rate = 0; }; + } // namespace zfp } // namespace filter } // namespace vtkm diff --git a/vtkm/filter/zfp/ZFPCompressor3D.h b/vtkm/filter/zfp/ZFPCompressor3D.h index 844054f11..6e38c8383 100644 --- a/vtkm/filter/zfp/ZFPCompressor3D.h +++ b/vtkm/filter/zfp/ZFPCompressor3D.h @@ -20,16 +20,19 @@ namespace filter { namespace zfp { -/// \brief Compress a scalar field using ZFP -/// Takes as input a 1D array and generates on +/// \brief Compress a scalar field using ZFP. +/// +/// Takes as input a 3D array and generates an /// output of compressed data. /// @warning -/// This filter is currently only supports 1D volumes. +/// This filter is currently only supports 3D structured cell sets. class VTKM_FILTER_ZFP_EXPORT ZFPCompressor3D : public vtkm::filter::FilterField { public: + /// @brief Specifies the rate of compression. void SetRate(vtkm::Float64 _rate) { rate = _rate; } + /// @copydoc SetRate vtkm::Float64 GetRate() { return rate; } private: @@ -37,6 +40,7 @@ private: vtkm::Float64 rate = 0; }; + } // namespace zfp } // namespace filter } // namespace vtkm diff --git a/vtkm/filter/zfp/ZFPDecompressor1D.h b/vtkm/filter/zfp/ZFPDecompressor1D.h index bf82bc001..ae7da1e01 100644 --- a/vtkm/filter/zfp/ZFPDecompressor1D.h +++ b/vtkm/filter/zfp/ZFPDecompressor1D.h @@ -20,16 +20,19 @@ namespace filter { namespace zfp { -/// \brief Compress a scalar field using ZFP -/// Takes as input a 1D array and generates on -/// output of compressed data. +/// \brief Decompress a scalar field using ZFP. +/// +/// Takes as input a 1D compressed array and generates +/// the decompressed version of the data. /// @warning -/// This filter is currently only supports 1D volumes. +/// This filter is currently only supports 1D structured cell sets. class VTKM_FILTER_ZFP_EXPORT ZFPDecompressor1D : public vtkm::filter::FilterField { public: + /// @brief Specifies the rate of compression. void SetRate(vtkm::Float64 _rate) { rate = _rate; } + /// @copydoc SetRate vtkm::Float64 GetRate() { return rate; } private: diff --git a/vtkm/filter/zfp/ZFPDecompressor2D.h b/vtkm/filter/zfp/ZFPDecompressor2D.h index 7c0d609de..44ecd3e1a 100644 --- a/vtkm/filter/zfp/ZFPDecompressor2D.h +++ b/vtkm/filter/zfp/ZFPDecompressor2D.h @@ -20,16 +20,19 @@ namespace filter { namespace zfp { -/// \brief Compress a scalar field using ZFP -/// Takes as input a 1D array and generates on -/// output of compressed data. +/// \brief Decompress a scalar field using ZFP. +/// +/// Takes as input a 2D compressed array and generates +/// the decompressed version of the data. /// @warning -/// This filter is currently only supports 1D volumes. +/// This filter is currently only supports 2D structured cell sets. class VTKM_FILTER_ZFP_EXPORT ZFPDecompressor2D : public vtkm::filter::FilterField { public: + /// @brief Specifies the rate of compression. void SetRate(vtkm::Float64 _rate) { rate = _rate; } + /// @copydoc SetRate vtkm::Float64 GetRate() { return rate; } private: @@ -37,6 +40,7 @@ private: vtkm::Float64 rate = 0; }; + } // namespace zfp } // namespace filter } // namespace vtkm diff --git a/vtkm/filter/zfp/ZFPDecompressor3D.h b/vtkm/filter/zfp/ZFPDecompressor3D.h index 744c8cd32..fb5baa4db 100644 --- a/vtkm/filter/zfp/ZFPDecompressor3D.h +++ b/vtkm/filter/zfp/ZFPDecompressor3D.h @@ -20,16 +20,19 @@ namespace filter { namespace zfp { -/// \brief Compress a scalar field using ZFP -/// Takes as input a 1D array and generates on -/// output of compressed data. +/// \brief Decompress a scalar field using ZFP. +/// +/// Takes as input a 3D compressed array and generates +/// the decompressed version of the data. /// @warning -/// This filter is currently only supports 1D volumes. +/// This filter is currently only supports 3D structured cell sets. class VTKM_FILTER_ZFP_EXPORT ZFPDecompressor3D : public vtkm::filter::FilterField { public: + /// @brief Specifies the rate of compression. void SetRate(vtkm::Float64 _rate) { rate = _rate; } + /// @copydoc SetRate vtkm::Float64 GetRate() { return rate; } private: @@ -37,6 +40,7 @@ private: vtkm::Float64 rate = 0; }; + } // namespace zfp } // namespace filter } // namespace vtkm diff --git a/vtkm/internal/ExportMacros.h b/vtkm/internal/ExportMacros.h index 5a6ae17be..ef79e4a7e 100644 --- a/vtkm/internal/ExportMacros.h +++ b/vtkm/internal/ExportMacros.h @@ -85,7 +85,7 @@ // resolve to a single type instance // - Be a type ( or component of a types signature ) that can be passed between // dynamic libraries and requires RTTI support ( dynamic_cast ). -#if defined(VTKM_MSVC) || defined(VTKM_CUDA) +#if defined(VTKM_MSVC) || defined(VTKM_CUDA) || defined(VTKM_DOXYGEN_ONLY) #define VTKM_ALWAYS_EXPORT #define VTKM_NEVER_EXPORT #else diff --git a/vtkm/io/ErrorIO.h b/vtkm/io/ErrorIO.h index 638e090af..d9ff35e0f 100644 --- a/vtkm/io/ErrorIO.h +++ b/vtkm/io/ErrorIO.h @@ -19,6 +19,9 @@ namespace io VTKM_SILENCE_WEAK_VTABLE_WARNING_START +/// This class is thrown when VTK-m encounters an error with the file system. +/// This can happen if there is a problem with reading or writing a file such +/// as a bad filename. class VTKM_ALWAYS_EXPORT ErrorIO : public vtkm::cont::Error { public: diff --git a/vtkm/io/ImageReaderBase.h b/vtkm/io/ImageReaderBase.h index ffae5b9e1..76bd200f9 100644 --- a/vtkm/io/ImageReaderBase.h +++ b/vtkm/io/ImageReaderBase.h @@ -22,7 +22,7 @@ namespace io /// \brief Manages reading, and loading data from images /// /// `ImageReaderBase` implements methods for loading imaging data from a canvas or -/// ArrayHandle and storing that data in a vtkm::cont::DataSet. Image rgb values +/// ArrayHandle and storing that data in a vtkm::cont::DataSet. Image RGB values /// are represented as a point field in a 2D uniform dataset. /// /// `ImageReaderBase` implements virtual methods for reading files. Ideally, @@ -35,16 +35,20 @@ public: using ColorArrayType = vtkm::cont::ArrayHandle; explicit VTKM_CONT ImageReaderBase(const char* filename); + /// @brief Construct a reader to load data from the given file. explicit VTKM_CONT ImageReaderBase(const std::string& filename); virtual VTKM_CONT ~ImageReaderBase() noexcept; ImageReaderBase(const ImageReaderBase&) = delete; ImageReaderBase& operator=(const ImageReaderBase&) = delete; + /// @brief Load data from the file and return it in a `DataSet` object. VTKM_CONT const vtkm::cont::DataSet& ReadDataSet(); VTKM_CONT const vtkm::cont::DataSet& GetDataSet() const { return this->DataSet; } + /// @brief Get the name of the output field that will be created to hold color data. VTKM_CONT const std::string& GetPointFieldName() const { return this->PointFieldName; } + /// @brief Set the name of the output field that will be created to hold color data. VTKM_CONT void SetPointFieldName(const std::string& name) { this->PointFieldName = name; } VTKM_CONT const std::string& GetFileName() const { return this->FileName; } diff --git a/vtkm/io/ImageReaderPNG.h b/vtkm/io/ImageReaderPNG.h index c1dfb41c1..79e2d2f1b 100644 --- a/vtkm/io/ImageReaderPNG.h +++ b/vtkm/io/ImageReaderPNG.h @@ -17,16 +17,17 @@ namespace vtkm namespace io { -/// \brief Manages reading images using the PNG format via lodepng +/// @brief Reads images using the PNG format. /// -/// `ImageReaderPNG` extends `ImageReaderBase` and implements reading images in a valid -/// PNG format. It utilizes lodepng's decode file functions to read -/// PNG images that are automatically compressed to optimal sizes relative to -/// the actual bit complexity of the image. +/// `ImageReaderPNG` is constructed with the name of the file to read. The data +/// from the file is read by calling the `ReadDataSet` method. /// /// `ImageReaderPNG` will automatically upsample/downsample read image data /// to a 16 bit RGB no matter how the image is compressed. It is up to the user to /// decide the pixel format for input PNGs +/// +/// By default, the colors are stored in a field named "colors", but the name of the +/// field can optionally be changed using the `SetPointFieldName` method. class VTKM_IO_EXPORT ImageReaderPNG : public ImageReaderBase { using Superclass = ImageReaderBase; @@ -40,6 +41,7 @@ public: protected: VTKM_CONT void Read() override; }; + } } // namespace vtkm::io diff --git a/vtkm/io/ImageReaderPNM.h b/vtkm/io/ImageReaderPNM.h index d73d98afb..f60a903bd 100644 --- a/vtkm/io/ImageReaderPNM.h +++ b/vtkm/io/ImageReaderPNM.h @@ -17,14 +17,20 @@ namespace vtkm namespace io { -/// \brief Manages reading images using the PNM format +/// \brief Reads images using the PNM format. /// -/// `ImageReaderPNM` extends `ImageReaderBase`, and implements reading images from a -/// valid PNM format (for magic number P6). More details on the PNM -/// format can be found here: http://netpbm.sourceforge.net/doc/ppm.html +/// `ImageReaderPNM` is constructed with the name of the file to read. The data +/// from the file is read by calling the `ReadDataSet` method. +/// +/// Currently, `ImageReaderPNM` only supports files using the portable pixmap (PPM) +/// format (with magic number ``P6''). These files are most commonly stored with a +/// `.ppm` extension although the `.pnm` extension is also valid. +/// More details on the PNM format can be found here at +/// http://netpbm.sourceforge.net/doc/ppm.html +/// +/// By default, the colors are stored in a field named "colors", but the name of the +/// field can optionally be changed using the `SetPointFieldName` method. /// -/// When a file is read the parsed MagicNumber and MaxColorSize provided -/// are utilized to correctly parse the bits from the file class VTKM_IO_EXPORT ImageReaderPNM : public ImageReaderBase { using Superclass = ImageReaderBase; diff --git a/vtkm/io/ImageWriterBase.h b/vtkm/io/ImageWriterBase.h index f8805d881..acca8ba37 100644 --- a/vtkm/io/ImageWriterBase.h +++ b/vtkm/io/ImageWriterBase.h @@ -22,7 +22,7 @@ namespace io /// \brief Manages writing, and loading data from images /// /// `ImageWriterBase` implements methods for loading imaging data from a canvas or -/// ArrayHandle and storing that data in a vtkm::cont::DataSet. Image rgb values +/// ArrayHandle and storing that data in a vtkm::cont::DataSet. Image RGB values /// are represented as a point field in a 2D uniform dataset. /// /// `ImageWriterBase` can be constructed from a file, canvas, or ArrayHandle. It can @@ -38,12 +38,12 @@ public: using ColorArrayType = vtkm::cont::ArrayHandle; VTKM_CONT ImageWriterBase(const char* filename); + /// @brief Construct a writer to save data to the given file. VTKM_CONT ImageWriterBase(const std::string& filename); VTKM_CONT virtual ~ImageWriterBase() noexcept; ImageWriterBase(const ImageWriterBase&) = delete; ImageWriterBase& operator=(const ImageWriterBase&) = delete; - ///@{ /// \brief Write the color field of a data set to an image file. /// /// The `DataSet` must have a 2D structured cell set. @@ -54,7 +54,6 @@ public: /// VTKM_CONT virtual void WriteDataSet(const vtkm::cont::DataSet& dataSet, const std::string& colorField = {}); - ///@} enum class PixelDepth { @@ -62,12 +61,10 @@ public: PIXEL_16 }; - ///@{ - /// You can specify the number of bits used by each color channel with the `PixelDepth`. - /// + /// @brief Specify the number of bits used by each color channel. VTKM_CONT PixelDepth GetPixelDepth() const { return this->Depth; } + /// @brief Specify the number of bits used by each color channel. VTKM_CONT void SetPixelDepth(PixelDepth depth) { this->Depth = depth; } - ///@} VTKM_CONT const std::string& GetFileName() const { return this->FileName; } VTKM_CONT void SetFileName(const std::string& filename) { this->FileName = filename; } diff --git a/vtkm/io/ImageWriterPNG.h b/vtkm/io/ImageWriterPNG.h index d2e8e53e6..1744cada3 100644 --- a/vtkm/io/ImageWriterPNG.h +++ b/vtkm/io/ImageWriterPNG.h @@ -17,12 +17,14 @@ namespace vtkm namespace io { -/// \brief Manages writing images using the PNG format via lodepng +/// @brief Writes images using the PNG format. +/// +/// `ImageWriterPNG` is constructed with the name of the file to write. The data +/// is written to the file by calling the `WriteDataSet` method. +/// +/// When writing files, `ImageReaderPNG` automatically compresses data to optimal +/// sizes relative to the actual bit complexity of the provided image. /// -/// \c ImageWriterPNG extends vtkm::io::ImageWriterBase and implements writing images in a valid -/// PNG format. It utilizes lodepng's encode file functions to write -/// PNG images that are automatically compressed to optimal sizes relative to -/// the actual bit complexity of the image. /// class VTKM_IO_EXPORT ImageWriterPNG : public vtkm::io::ImageWriterBase { diff --git a/vtkm/io/ImageWriterPNM.h b/vtkm/io/ImageWriterPNM.h index 0ba088917..353002020 100644 --- a/vtkm/io/ImageWriterPNM.h +++ b/vtkm/io/ImageWriterPNM.h @@ -17,15 +17,16 @@ namespace vtkm namespace io { -/// \brief Manages writing images using the PNM format +/// \brief Writes images using the PNM format. /// -/// `ImageWriterPNM` extends `ImageWriterBase`, and implements writing images in a -/// valid PNM format (for magic number P6). More details on the PNM -/// format can be found here: http://netpbm.sourceforge.net/doc/ppm.html +/// `ImageWriterPNM` is constructed with the name of the file to write. The data +/// is written to the file by calling the `WriteDataSet` method. +/// +/// `ImageWriterPNM` writes images in PNM format (for magic number P6). +/// These files are most commonly stored with a `.ppm` extension although the +/// `.pnm` extension is also valid. More details on the PNM format can be found at +/// http://netpbm.sourceforge.net/doc/ppm.html /// -/// When a file is writen the MaxColorValue found in the file is used to -/// determine the PixelType required to stored PixelType is instead dependent -/// upon the read MaxColorValue obtained from the file class VTKM_IO_EXPORT ImageWriterPNM : public vtkm::io::ImageWriterBase { using Superclass = vtkm::io::ImageWriterBase; diff --git a/vtkm/io/VTKDataSetReader.h b/vtkm/io/VTKDataSetReader.h index 49e4b4537..1cb1e959c 100644 --- a/vtkm/io/VTKDataSetReader.h +++ b/vtkm/io/VTKDataSetReader.h @@ -17,10 +17,16 @@ namespace vtkm namespace io { +/// @brief Reads a legacy VTK file. +/// +/// By convention, legacy VTK files have a `.vtk` extension. +/// This class should be constructed with a filename, and the data +/// read with `ReadDataSet`. class VTKM_IO_EXPORT VTKDataSetReader : public VTKDataSetReaderBase { public: VTKM_CONT VTKDataSetReader(const char* fileName); + /// @brief Construct a reader to load data from the given file. VTKM_CONT VTKDataSetReader(const std::string& fileName); VTKM_CONT ~VTKDataSetReader() override; @@ -35,6 +41,7 @@ private: std::unique_ptr Reader; }; + } } // vtkm::io diff --git a/vtkm/io/VTKDataSetReaderBase.h b/vtkm/io/VTKDataSetReaderBase.h index bd75ed7ca..00d8543b0 100644 --- a/vtkm/io/VTKDataSetReaderBase.h +++ b/vtkm/io/VTKDataSetReaderBase.h @@ -116,7 +116,8 @@ public: VTKDataSetReaderBase(const VTKDataSetReaderBase&) = delete; void operator=(const VTKDataSetReaderBase&) = delete; - const VTKM_CONT vtkm::cont::DataSet& ReadDataSet(); + /// @brief Load data from the file and return it in a `DataSet` object. + VTKM_CONT const vtkm::cont::DataSet& ReadDataSet(); const vtkm::cont::DataSet& GetDataSet() const { return this->DataSet; } diff --git a/vtkm/io/VTKDataSetWriter.h b/vtkm/io/VTKDataSetWriter.h index 4b50b0d49..d00adbbed 100644 --- a/vtkm/io/VTKDataSetWriter.h +++ b/vtkm/io/VTKDataSetWriter.h @@ -26,24 +26,31 @@ enum struct FileType BINARY }; -struct VTKM_IO_EXPORT VTKDataSetWriter +/// @brief Reads a legacy VTK file. +/// +/// By convention, legacy VTK files have a `.vtk` extension. +/// This class should be constructed with a filename, and the data +/// read with `ReadDataSet`. +class VTKM_IO_EXPORT VTKDataSetWriter { public: VTKM_CONT VTKDataSetWriter(const char* fileName); + /// @brief Construct a writer to save data to the given file. VTKM_CONT VTKDataSetWriter(const std::string& fileName); + /// @brief Write data from the given `DataSet` object to the file specified in the constructor. VTKM_CONT void WriteDataSet(const vtkm::cont::DataSet& dataSet) const; - /// \brief Get whether the file will be written in ASCII or binary format. + /// @brief Get whether the file will be written in ASCII or binary format. /// VTKM_CONT vtkm::io::FileType GetFileType() const; - /// \{ - /// \brief Set whether the file will be written in ASCII or binary format. + /// @brief Set whether the file will be written in ASCII or binary format. VTKM_CONT void SetFileType(vtkm::io::FileType type); + /// @brief Set whether the file will be written in ASCII or binary format. VTKM_CONT void SetFileTypeToAscii() { this->SetFileType(vtkm::io::FileType::ASCII); } + /// @brief Set whether the file will be written in ASCII or binary format. VTKM_CONT void SetFileTypeToBinary() { this->SetFileType(vtkm::io::FileType::BINARY); } - /// \} private: std::string FileName; diff --git a/vtkm/rendering/Actor.h b/vtkm/rendering/Actor.h index 820de6bf6..e2b9ad784 100644 --- a/vtkm/rendering/Actor.h +++ b/vtkm/rendering/Actor.h @@ -23,18 +23,33 @@ namespace vtkm namespace rendering { +/// @brief An item to be rendered. +/// +/// The `Actor` holds the geometry from a `vtkm::cont::DataSet` as well as other visual +/// properties that define how the geometry should look when it is rendered. class VTKM_RENDERING_EXPORT Actor { public: + /// Create an `Actor` object that renders a set of cells positioned by a given coordiante + /// system. A field to apply psudocoloring is also provided. The default colormap is applied. + /// The cells, coordinates, and field are typically pulled from a `vtkm::cont::DataSet` object. Actor(const vtkm::cont::UnknownCellSet& cells, const vtkm::cont::CoordinateSystem& coordinates, const vtkm::cont::Field& scalarField); + /// Create an `Actor` object that renders a set of cells positioned by a given coordiante + /// system. A field to apply psudocoloring is also provided. A color table providing the map + /// from scalar values to colors is also provided. + /// The cells, coordinates, and field are typically pulled from a `vtkm::cont::DataSet` object. Actor(const vtkm::cont::UnknownCellSet& cells, const vtkm::cont::CoordinateSystem& coordinates, const vtkm::cont::Field& scalarField, const vtkm::cont::ColorTable& colorTable); + /// Create an `Actor` object that renders a set of cells positioned by a given coordiante + /// system. A constant color to apply to the object is also provided. + /// The cells and coordinates are typically pulled from a `vtkm::cont::DataSet` object. + // Why do you have to provide a `Field` if a constant color is provided? Actor(const vtkm::cont::UnknownCellSet& cells, const vtkm::cont::CoordinateSystem& coordinates, const vtkm::cont::Field& scalarField, @@ -63,6 +78,11 @@ public: const vtkm::Bounds& GetSpatialBounds() const; + /// @brief Specifies the range for psudocoloring. + /// + /// When coloring data by mapping a scalar field to colors, this is the range used for + /// the colors provided by the table. If a range is not provided, the range of data in the + /// field is used. void SetScalarRange(const vtkm::Range& scalarRange); private: diff --git a/vtkm/rendering/Camera.h b/vtkm/rendering/Camera.h index 2e8113db0..abd82377a 100644 --- a/vtkm/rendering/Camera.h +++ b/vtkm/rendering/Camera.h @@ -25,6 +25,15 @@ namespace vtkm namespace rendering { +/// @brief Specifies the viewport for a rendering. +/// +/// The `vtkm::rendering::View` object holds a `Camera` object to specify from +/// what perspective the rendering should take place. +/// +/// A `Camera` operates in one of two major modes: 2D mode +/// or 3D mode. 2D mode is designed for looking at flat geometry (or close to flat +/// geometry) that is parallel to the x-y plane. 3D mode provides the freedom to +/// place the camera anywhere in 3D space. class VTKM_RENDERING_EXPORT Camera { struct Camera3DStruct @@ -122,22 +131,25 @@ public: vtkm::Float32& bottom, vtkm::Float32& top) const; - /// \brief The mode of the camera (2D or 3D). + /// @brief The mode of the camera (2D or 3D). /// - /// \c vtkm::Camera can be set to a 2D or 3D mode. 2D mode is used for + /// `vtkm::rendering::Camera` can be set to a 2D or 3D mode. 2D mode is used for /// looking at data in the x-y plane. 3D mode allows the camera to be /// positioned anywhere and pointing at any place in 3D. /// VTKM_CONT vtkm::rendering::Camera::Mode GetMode() const { return this->ModeType; } + /// @copydoc GetMode VTKM_CONT void SetMode(vtkm::rendering::Camera::Mode mode) { this->ModeType = mode; } + /// @copydoc GetMode VTKM_CONT void SetModeTo3D() { this->SetMode(vtkm::rendering::Camera::Mode::ThreeD); } + /// @copydoc GetMode VTKM_CONT void SetModeTo2D() { this->SetMode(vtkm::rendering::Camera::Mode::TwoD); } - /// \brief The clipping range of the camera. + /// @brief The clipping range of the camera. /// /// The clipping range establishes the near and far clipping planes. These /// clipping planes are parallel to the viewing plane. The planes are defined @@ -152,25 +164,28 @@ public: /// VTKM_CONT vtkm::Range GetClippingRange() const { return vtkm::Range(this->NearPlane, this->FarPlane); } + /// @copydoc GetClippingRange VTKM_CONT void SetClippingRange(vtkm::Float32 nearPlane, vtkm::Float32 farPlane) { this->NearPlane = nearPlane; this->FarPlane = farPlane; } + /// @copydoc GetClippingRange VTKM_CONT void SetClippingRange(vtkm::Float64 nearPlane, vtkm::Float64 farPlane) { this->SetClippingRange(static_cast(nearPlane), static_cast(farPlane)); } + /// @copydoc GetClippingRange VTKM_CONT void SetClippingRange(const vtkm::Range& nearFarRange) { this->SetClippingRange(nearFarRange.Min, nearFarRange.Max); } - /// \brief The viewport of the projection + /// @brief The viewport of the projection /// /// The projection of the camera can be offset to be centered around a subset /// of the rendered image. This is established with a "viewport," which is @@ -189,6 +204,7 @@ public: bottom = this->ViewportBottom; top = this->ViewportTop; } + /// @copydoc GetViewport VTKM_CONT void GetViewport(vtkm::Float64& left, vtkm::Float64& right, @@ -200,12 +216,14 @@ public: bottom = this->ViewportBottom; top = this->ViewportTop; } + /// @copydoc GetViewport VTKM_CONT vtkm::Bounds GetViewport() const { return vtkm::Bounds( this->ViewportLeft, this->ViewportRight, this->ViewportBottom, this->ViewportTop, 0.0, 0.0); } + /// @copydoc GetViewport VTKM_CONT void SetViewport(vtkm::Float32 left, vtkm::Float32 right, vtkm::Float32 bottom, vtkm::Float32 top) { @@ -214,6 +232,7 @@ public: this->ViewportBottom = bottom; this->ViewportTop = top; } + /// @copydoc GetViewport VTKM_CONT void SetViewport(vtkm::Float64 left, vtkm::Float64 right, vtkm::Float64 bottom, vtkm::Float64 top) { @@ -222,6 +241,7 @@ public: static_cast(bottom), static_cast(top)); } + /// @copydoc GetViewport VTKM_CONT void SetViewport(const vtkm::Bounds& viewportBounds) { @@ -229,60 +249,66 @@ public: viewportBounds.X.Min, viewportBounds.X.Max, viewportBounds.Y.Min, viewportBounds.Y.Max); } - /// \brief The focal point the camera is looking at in 3D mode + /// @brief The focal point the camera is looking at in 3D mode /// /// When in 3D mode, the camera is set up to be facing the \c LookAt /// position. If \c LookAt is set, the mode is changed to 3D mode. /// VTKM_CONT const vtkm::Vec3f_32& GetLookAt() const { return this->Camera3D.LookAt; } + /// @copydoc GetLookAt VTKM_CONT void SetLookAt(const vtkm::Vec3f_32& lookAt) { this->SetModeTo3D(); this->Camera3D.LookAt = lookAt; } + /// @copydoc GetLookAt VTKM_CONT void SetLookAt(const vtkm::Vec& lookAt) { this->SetLookAt(vtkm::Vec(lookAt)); } - /// \brief The spatial position of the camera in 3D mode + /// @brief The spatial position of the camera in 3D mode /// /// When in 3D mode, the camera is modeled to be at a particular location. If - /// \c Position is set, the mode is changed to 3D mode. + /// `Position` is set, the mode is changed to 3D mode. /// VTKM_CONT const vtkm::Vec3f_32& GetPosition() const { return this->Camera3D.Position; } + /// @copydoc GetPosition VTKM_CONT void SetPosition(const vtkm::Vec3f_32& position) { this->SetModeTo3D(); this->Camera3D.Position = position; } + /// @copydoc GetPosition VTKM_CONT void SetPosition(const vtkm::Vec3f_64& position) { this->SetPosition(vtkm::Vec3f_32(position)); } - /// \brief The up orientation of the camera in 3D mode + /// @brief The up orientation of the camera in 3D mode /// /// When in 3D mode, the camera is modeled to be at a particular location and /// looking at a particular spot. The view up vector orients the rotation of /// the image so that the top of the image is in the direction pointed to by - /// view up. If \c ViewUp is set, the mode is changed to 3D mode. + /// view up. If `ViewUp` is set, the mode is changed to 3D mode. /// VTKM_CONT const vtkm::Vec3f_32& GetViewUp() const { return this->Camera3D.ViewUp; } + /// @copydoc GetViewUp VTKM_CONT void SetViewUp(const vtkm::Vec3f_32& viewUp) { this->SetModeTo3D(); this->Camera3D.ViewUp = viewUp; } + /// @copydoc GetViewUp VTKM_CONT void SetViewUp(const vtkm::Vec3f_64& viewUp) { this->SetViewUp(vtkm::Vec3f_32(viewUp)); } - /// \brief The xscale of the camera + /// @brief The xscale of the camera /// /// The xscale forces the 2D curves to be full-frame /// @@ -290,16 +316,18 @@ public: /// VTKM_CONT vtkm::Float32 GetXScale() const { return this->Camera2D.XScale; } + /// @copydoc GetXScale VTKM_CONT void SetXScale(vtkm::Float32 xscale) { this->SetModeTo2D(); this->Camera2D.XScale = xscale; } + /// @copydoc GetXScale VTKM_CONT void SetXScale(vtkm::Float64 xscale) { this->SetXScale(static_cast(xscale)); } - /// \brief The field of view angle + /// @brief The field of view angle /// /// The field of view defines the angle (in degrees) that are visible from /// the camera position. @@ -308,71 +336,78 @@ public: /// VTKM_CONT vtkm::Float32 GetFieldOfView() const { return this->Camera3D.FieldOfView; } + /// @copydoc GetFieldOfView VTKM_CONT void SetFieldOfView(vtkm::Float32 fov) { this->SetModeTo3D(); this->Camera3D.FieldOfView = fov; } + /// @copydoc GetFieldOfView VTKM_CONT void SetFieldOfView(vtkm::Float64 fov) { this->SetFieldOfView(static_cast(fov)); } - /// \brief Pans the camera + /// @brief Pans the camera /// + /// Panning the camera shifts the view horizontially and/or vertically with + /// respect to the image plane. + /// + /// Panning works in either 2D or 3D mode. void Pan(vtkm::Float32 dx, vtkm::Float32 dy); - - /// \brief Pans the camera - /// + /// @copydoc Pan VTKM_CONT void Pan(vtkm::Float64 dx, vtkm::Float64 dy) { this->Pan(static_cast(dx), static_cast(dy)); } + /// @copydoc Pan VTKM_CONT void Pan(vtkm::Vec2f_32 direction) { this->Pan(direction[0], direction[1]); } - + /// @copydoc Pan VTKM_CONT void Pan(vtkm::Vec2f_64 direction) { this->Pan(direction[0], direction[1]); } - + /// @copydoc Pan VTKM_CONT vtkm::Vec2f_32 GetPan() const { vtkm::Vec2f_32 pan; + // Note that the 2D and 3D pan are always set the same. pan[0] = this->Camera3D.XPan; pan[1] = this->Camera3D.YPan; return pan; } - /// \brief Zooms the camera in or out + /// @brief Zooms the camera in or out /// /// Zooming the camera scales everything in the image up or down. Positive /// zoom makes the geometry look bigger or closer. Negative zoom has the /// opposite effect. A zoom of 0 has no effect. /// + /// Zooming works in either 2D or 3D mode. void Zoom(vtkm::Float32 zoom); - + /// @copydoc Zoom VTKM_CONT void Zoom(vtkm::Float64 zoom) { this->Zoom(static_cast(zoom)); } - + /// @copydoc Zoom VTKM_CONT vtkm::Float32 GetZoom() const { return this->Camera3D.Zoom; } - /// \brief Moves the camera as if a point was dragged along a sphere. + /// @brief Moves the camera as if a point was dragged along a sphere. /// - /// \c TrackballRotate takes the normalized screen coordinates (in the range - /// -1 to 1) and rotates the camera around the \c LookAt position. The rotation - /// first projects the points to a sphere around the \c LookAt position. The + /// `TrackballRotate()` takes the normalized screen coordinates (in the range + /// -1 to 1) and rotates the camera around the `LookAt` position. The rotation + /// first projects the points to a sphere around the `LookAt` position. The /// camera is then rotated as if the start point was dragged to the end point /// along with the world. /// - /// \c TrackballRotate changes the mode to 3D. + /// `TrackballRotate()` changes the mode to 3D. /// void TrackballRotate(vtkm::Float32 startX, vtkm::Float32 startY, vtkm::Float32 endX, vtkm::Float32 endY); - + /// @copydoc TrackballRotate VTKM_CONT void TrackballRotate(vtkm::Float64 startX, vtkm::Float64 startY, @@ -385,30 +420,25 @@ public: static_cast(endY)); } - /// \brief Set up the camera to look at geometry + /// @brief Set up the camera to look at geometry /// - /// \c ResetToBounds takes a \c Bounds structure containing the bounds in + /// `ResetToBounds()` takes a `vtkm::Bounds` structure containing the bounds in /// 3D space that contain the geometry being rendered. This method sets up /// the camera so that it is looking at this region in space. The view - /// direction is preserved. + /// direction is preserved. `ResetToBounds()` can also take optional padding + /// that the viewpoint should preserve around the object. Padding is specified + /// as the fraction of the bounds to add as padding. /// void ResetToBounds(const vtkm::Bounds& dataBounds); - - /// \brief Set up the camera to look at geometry with padding - /// - /// \c ResetToBounds takes a \c Bounds structure containing the bounds in - /// 3D space that contain the geometry being rendered and a \c Float64 value - /// representing the percent that a view should be padded in x, y, and z. - /// This method sets up the camera so that it is looking at this region in - // space with the given padding percent. The view direction is preserved. - /// + /// @copydoc ResetToBounds void ResetToBounds(const vtkm::Bounds& dataBounds, vtkm::Float64 dataViewPadding); + /// @copydoc ResetToBounds void ResetToBounds(const vtkm::Bounds& dataBounds, vtkm::Float64 XDataViewPadding, vtkm::Float64 YDataViewPadding, vtkm::Float64 ZDataViewPadding); - /// \brief Roll the camera + /// @brief Roll the camera /// /// Rotates the camera around the view direction by the given angle. The /// angle is given in degrees. @@ -416,68 +446,74 @@ public: /// Roll is currently only supported for 3D cameras. /// void Roll(vtkm::Float32 angleDegrees); - + /// @copydoc Roll VTKM_CONT void Roll(vtkm::Float64 angleDegrees) { this->Roll(static_cast(angleDegrees)); } - /// \brief Rotate the camera about the view up vector centered at the focal point. + /// @brief Rotate the camera about the view up vector centered at the focal point. /// - /// Note that the view up vector is whatever was set via SetViewUp, and is + /// Note that the view up vector is whatever was set via `SetViewUp()`, and is /// not necessarily perpendicular to the direction of projection. The angle is /// given in degrees. /// - /// Azimuth only makes sense for 3D cameras, so the camera mode will be set + /// `Azimuth()` only makes sense for 3D cameras, so the camera mode will be set /// to 3D when this method is called. /// void Azimuth(vtkm::Float32 angleDegrees); - + /// @copydoc Azimuth VTKM_CONT void Azimuth(vtkm::Float64 angleDegrees) { this->Azimuth(static_cast(angleDegrees)); } - /// \brief Rotate the camera vertically around the focal point. + /// @brief Rotate the camera vertically around the focal point. /// /// Specifically, this rotates the camera about the cross product of the /// negative of the direction of projection and the view up vector, using the - /// focal point (LookAt) as the center of rotation. The angle is given + /// focal point (`LookAt`) as the center of rotation. The angle is given /// in degrees. /// - /// Elevation only makes sense for 3D cameras, so the camera mode will be set + /// `Elevation()` only makes sense for 3D cameras, so the camera mode will be set /// to 3D when this method is called. /// void Elevation(vtkm::Float32 angleDegrees); - + /// @copydoc Elevation VTKM_CONT void Elevation(vtkm::Float64 angleDegrees) { this->Elevation(static_cast(angleDegrees)); } - /// \brief Move the camera toward or away from the focal point. + /// @brief Move the camera toward or away from the focal point. /// /// Specifically, this divides the camera's distance from the focal point - /// (LookAt) by the given value. Use a value greater than one to dolly in + /// (`LookAt`) by the given value. Use a value greater than one to dolly in /// toward the focal point, and use a value less than one to dolly-out away /// from the focal point. /// - /// Dolly only makes sense for 3D cameras, so the camera mode will be set to + /// `Dolly()` has a similar effect as `Zoom()` since an object will appear larger + /// when the camera is closer. However, because you are moving the camera, `Dolly()` + /// can change the perspective relative to objects such as moving inside an object + /// for an interior perspective whereas `Zoom()` will just change the size of the + /// visible objects. + /// + /// `Dolly()` only makes sense for 3D cameras, so the camera mode will be set to /// 3D when this method is called. /// void Dolly(vtkm::Float32 value); - + /// @copydoc Dolly VTKM_CONT void Dolly(vtkm::Float64 value) { this->Dolly(static_cast(value)); } - /// \brief The viewable region in the x-y plane + /// @brief The viewable region in the x-y plane /// /// When the camera is in 2D, it is looking at some region of the x-y plane. /// The region being looked at is defined by the range in x (determined by /// the left and right sides) and by the range in y (determined by the bottom /// and top sides). /// - /// \c SetViewRange2D changes the camera mode to 2D. + /// `SetViewRange2D()` changes the camera mode to 2D. /// VTKM_CONT void GetViewRange2D(vtkm::Float32& left, @@ -490,6 +526,7 @@ public: bottom = this->Camera2D.Bottom; top = this->Camera2D.Top; } + /// @copydoc GetViewRange2D VTKM_CONT vtkm::Bounds GetViewRange2D() const { @@ -500,6 +537,7 @@ public: 0.0, 0.0); } + /// @copydoc GetViewRange2D VTKM_CONT void SetViewRange2D(vtkm::Float32 left, vtkm::Float32 right, @@ -516,6 +554,7 @@ public: this->Camera2D.YPan = 0; this->Camera2D.Zoom = 1; } + /// @copydoc GetViewRange2D VTKM_CONT void SetViewRange2D(vtkm::Float64 left, vtkm::Float64 right, @@ -527,6 +566,7 @@ public: static_cast(bottom), static_cast(top)); } + /// @copydoc GetViewRange2D VTKM_CONT void SetViewRange2D(const vtkm::Range& xRange, const vtkm::Range& yRange) { diff --git a/vtkm/rendering/Canvas.h b/vtkm/rendering/Canvas.h index 6da78559b..b58a9639a 100644 --- a/vtkm/rendering/Canvas.h +++ b/vtkm/rendering/Canvas.h @@ -31,6 +31,7 @@ namespace rendering class WorldAnnotator; +/// @brief Represents the image space that is the target of rendering. class VTKM_RENDERING_EXPORT Canvas { public: @@ -38,34 +39,49 @@ public: using DepthBufferType = vtkm::cont::ArrayHandle; using FontTextureType = vtkm::rendering::Texture2D<1>; + /// Construct a canvas of a given width and height. Canvas(vtkm::Id width = 1024, vtkm::Id height = 1024); virtual ~Canvas(); + /// Create a new `Canvas` object of the same subtype as this one. virtual vtkm::rendering::Canvas* NewCopy() const; + /// @brief Clear out the image buffers. virtual void Clear(); + /// @brief Blend the foreground data with the background color. + /// + /// When a render is started, it is given a zeroed background rather than the + /// background color specified by `SetBackgroundColor()`. This is because when + /// blending pixel fragments of transparent objects the background color can + /// interfere. Call this method after the render is completed for the final + /// blend to get the proper background color. virtual void BlendBackground(); + /// @brief The width of the image. VTKM_CONT vtkm::Id GetWidth() const; + /// @brief The height of the image. VTKM_CONT vtkm::Id GetHeight() const; + /// @brief Get the color channels of the image. VTKM_CONT const ColorBufferType& GetColorBuffer() const; + /// @copydoc GetColorBuffer VTKM_CONT ColorBufferType& GetColorBuffer(); + /// @brief Get the depth channel of the image. VTKM_CONT const DepthBufferType& GetDepthBuffer() const; + /// @copydoc GetDepthBuffer VTKM_CONT DepthBufferType& GetDepthBuffer(); - ///@{ /// \brief Gets the image in this `Canvas` as a `vtkm::cont::DataSet`. /// /// The returned `DataSet` will be a uniform structured 2D grid. The color and depth @@ -77,22 +93,27 @@ public: /// VTKM_CONT vtkm::cont::DataSet GetDataSet(const std::string& colorFieldName = "color", const std::string& depthFieldName = "depth") const; + /// @copydoc GetDataSet VTKM_CONT vtkm::cont::DataSet GetDataSet(const char* colorFieldName, const char* depthFieldName = "depth") const; - ///@} + /// @brief Change the size of the image. VTKM_CONT void ResizeBuffers(vtkm::Id width, vtkm::Id height); + /// @brief Specify the background color. VTKM_CONT const vtkm::rendering::Color& GetBackgroundColor() const; + /// @copydoc GetBackgroundColor VTKM_CONT void SetBackgroundColor(const vtkm::rendering::Color& color); + /// @brief Specify the foreground color used for annotations. VTKM_CONT const vtkm::rendering::Color& GetForegroundColor() const; + /// @copydoc GetForegroundColor VTKM_CONT void SetForegroundColor(const vtkm::rendering::Color& color); @@ -111,6 +132,10 @@ public: virtual void SetViewToScreenSpace(const vtkm::rendering::Camera& camera, bool clip); virtual void SetViewportClipping(const vtkm::rendering::Camera&, bool) {} + /// @brief Save the rendered image. + /// + /// If the filename ends with ".png", it will be saved in the portable network + /// graphic format. Otherwise, the file will be saved in Netbpm portable pixmap format. virtual void SaveAs(const std::string& fileName) const; /// Creates a WorldAnnotator of a type that is paired with this Canvas. Other diff --git a/vtkm/rendering/CanvasRayTracer.h b/vtkm/rendering/CanvasRayTracer.h index 056f1a30b..171dbfa54 100644 --- a/vtkm/rendering/CanvasRayTracer.h +++ b/vtkm/rendering/CanvasRayTracer.h @@ -20,9 +20,12 @@ namespace vtkm namespace rendering { +/// Represents the image space that is the target of rendering using the internal ray +/// tracing code. class VTKM_RENDERING_EXPORT CanvasRayTracer : public Canvas { public: + /// Construct a canvas of a given width and height. CanvasRayTracer(vtkm::Id width = 1024, vtkm::Id height = 1024); ~CanvasRayTracer(); diff --git a/vtkm/rendering/Color.h b/vtkm/rendering/Color.h index 54bcd4afa..f942f13a6 100644 --- a/vtkm/rendering/Color.h +++ b/vtkm/rendering/Color.h @@ -19,35 +19,46 @@ namespace vtkm namespace rendering { -/// \brief It's a color! +/// @brief Representation of a color. /// -/// This class provides the basic representation of a color. This class was -/// Ported from EAVL. Originally created by Jeremy Meredith, Dave Pugmire, -/// and Sean Ahern. +/// The color is defined as red, green, and blue intensities as well as +/// an alpha representation of transparency (RGBA). The class provides +/// mechanisms to retrieve the color as 8-bit integers or floating point +/// values in the range [0, 1]. /// class Color { public: vtkm::Vec4f_32 Components; + /// @brief Create a black color. VTKM_EXEC_CONT Color() : Components(0, 0, 0, 1) { } + /// @brief Create a color with specified RGBA values. + /// + /// The values are floating point and in the range [0, 1]. VTKM_EXEC_CONT Color(vtkm::Float32 r_, vtkm::Float32 g_, vtkm::Float32 b_, vtkm::Float32 a_ = 1.f) : Components(r_, g_, b_, a_) { } + /// @brief Create a color with specified RGBA values. + /// + /// The values are floating point and in the range [0, 1]. VTKM_EXEC_CONT Color(const vtkm::Vec4f_32& components) : Components(components) { } + /// @brief Set the color value from 8 bit RGBA components. + /// + /// The components are packed together into a 32-bit (4-byte) values. VTKM_EXEC_CONT void SetComponentFromByte(vtkm::Int32 i, vtkm::UInt8 v) { diff --git a/vtkm/rendering/Mapper.h b/vtkm/rendering/Mapper.h index df3c95c69..b6fb70570 100644 --- a/vtkm/rendering/Mapper.h +++ b/vtkm/rendering/Mapper.h @@ -21,6 +21,10 @@ namespace vtkm namespace rendering { +/// @brief Converts data into commands to a rendering system. +/// +/// This is the base class for all mapper classes in VTK-m. Different concrete +/// derived classes can provide different representations and rendering techniques. class VTKM_RENDERING_EXPORT Mapper { public: diff --git a/vtkm/rendering/MapperCylinder.h b/vtkm/rendering/MapperCylinder.h index bb5840fab..805b63bee 100644 --- a/vtkm/rendering/MapperCylinder.h +++ b/vtkm/rendering/MapperCylinder.h @@ -22,7 +22,7 @@ namespace rendering { /** - * \brief MapperCylinder renderers edges from a cell set + * \brief `MapperCylinder` renderers edges from a cell set * and renders them as cylinders via ray tracing. * */ diff --git a/vtkm/rendering/MapperGlyphBase.cxx b/vtkm/rendering/MapperGlyphBase.cxx index a23120927..906ec5558 100644 --- a/vtkm/rendering/MapperGlyphBase.cxx +++ b/vtkm/rendering/MapperGlyphBase.cxx @@ -39,18 +39,18 @@ vtkm::rendering::Canvas* MapperGlyphBase::GetCanvas() const return this->Canvas; } -vtkm::cont::Field::Association MapperGlyphBase::GetGlyphAssociation() const +vtkm::cont::Field::Association MapperGlyphBase::GetAssociation() const { - return this->GlyphAssociation; + return this->Association; } -void MapperGlyphBase::SetGlyphAssociation(vtkm::cont::Field::Association association) +void MapperGlyphBase::SetAssociation(vtkm::cont::Field::Association association) { switch (association) { case vtkm::cont::Field::Association::Cells: case vtkm::cont::Field::Association::Points: - this->GlyphAssociation = association; + this->Association = association; break; default: throw vtkm::cont::ErrorBadValue("Invalid glyph association."); @@ -59,22 +59,22 @@ void MapperGlyphBase::SetGlyphAssociation(vtkm::cont::Field::Association associa bool MapperGlyphBase::GetUseCells() const { - return this->GlyphAssociation == vtkm::cont::Field::Association::Cells; + return this->Association == vtkm::cont::Field::Association::Cells; } void MapperGlyphBase::SetUseCells() { - this->SetGlyphAssociation(vtkm::cont::Field::Association::Cells); + this->SetAssociation(vtkm::cont::Field::Association::Cells); } bool MapperGlyphBase::GetUsePoints() const { - return this->GlyphAssociation == vtkm::cont::Field::Association::Points; + return this->Association == vtkm::cont::Field::Association::Points; } void MapperGlyphBase::SetUsePoints() { - this->SetGlyphAssociation(vtkm::cont::Field::Association::Points); + this->SetAssociation(vtkm::cont::Field::Association::Points); } bool MapperGlyphBase::GetUseNodes() const diff --git a/vtkm/rendering/MapperGlyphBase.h b/vtkm/rendering/MapperGlyphBase.h index 76a6f1fe9..06f0b7e01 100644 --- a/vtkm/rendering/MapperGlyphBase.h +++ b/vtkm/rendering/MapperGlyphBase.h @@ -43,20 +43,20 @@ public: /// The glyph mapper will place glyphs over locations specified by either the points /// or the cells of a mesh. The glyph may also be oriented by a scalar field with the /// same association. - virtual vtkm::cont::Field::Association GetGlyphAssociation() const; - /// @copydoc GetGlyphAssociation - virtual void SetGlyphAssociation(vtkm::cont::Field::Association association); - /// @copydoc GetGlyphAssociation + virtual vtkm::cont::Field::Association GetAssociation() const; + /// @copydoc GetAssociation + virtual void SetAssociation(vtkm::cont::Field::Association association); + /// @copydoc GetAssociation virtual bool GetUseCells() const; - /// @copydoc GetGlyphAssociation + /// @copydoc GetAssociation virtual void SetUseCells(); - /// @copydoc GetGlyphAssociation + /// @copydoc GetAssociation virtual bool GetUsePoints() const; - /// @copydoc GetGlyphAssociation + /// @copydoc GetAssociation virtual void SetUsePoints(); - VTKM_DEPRECATED(2.2, "Use GetUsePoints() or GetGlyphAssociation().") + VTKM_DEPRECATED(2.2, "Use GetUsePoints() or GetAssociation().") virtual bool GetUseNodes() const; - VTKM_DEPRECATED(2.2, "Use SetUsePoints() or SetGlyphAssociation().") + VTKM_DEPRECATED(2.2, "Use SetUsePoints() or SetAssociation().") virtual void SetUseNodes(); // These options do not seem to be supported yet. @@ -102,7 +102,7 @@ protected: vtkm::rendering::CanvasRayTracer* Canvas = nullptr; bool CompositeBackground = true; - vtkm::cont::Field::Association GlyphAssociation = vtkm::cont::Field::Association::Points; + vtkm::cont::Field::Association Association = vtkm::cont::Field::Association::Points; bool UseStride = false; vtkm::Id Stride = 1; diff --git a/vtkm/rendering/MapperGlyphScalar.cxx b/vtkm/rendering/MapperGlyphScalar.cxx index b6ccd1a54..b72e235f1 100644 --- a/vtkm/rendering/MapperGlyphScalar.cxx +++ b/vtkm/rendering/MapperGlyphScalar.cxx @@ -370,22 +370,22 @@ void MapperGlyphScalar::RenderCells(const vtkm::cont::UnknownCellSet& cellset, { vtkm::Float32 minSize = baseSize - baseSize * this->ScaleDelta; vtkm::Float32 maxSize = baseSize + baseSize * this->ScaleDelta; - if (this->GlyphAssociation == vtkm::cont::Field::Association::Points) + if (this->Association == vtkm::cont::Field::Association::Points) { glyphExtractor.ExtractCoordinates(processedCoords, processedField, minSize, maxSize); } - else // this->GlyphAssociation == vtkm::cont::Field::Association::Cells + else // this->Association == vtkm::cont::Field::Association::Cells { glyphExtractor.ExtractCells(processedCellSet, processedField, minSize, maxSize); } } else { - if (this->GlyphAssociation == vtkm::cont::Field::Association::Points) + if (this->Association == vtkm::cont::Field::Association::Points) { glyphExtractor.ExtractCoordinates(processedCoords, baseSize); } - else // this->GlyphAssociation == vtkm::cont::Field::Association::Cells + else // this->Association == vtkm::cont::Field::Association::Cells { glyphExtractor.ExtractCells(processedCellSet, baseSize); } diff --git a/vtkm/rendering/MapperGlyphVector.cxx b/vtkm/rendering/MapperGlyphVector.cxx index 8690838ee..18b375a7b 100644 --- a/vtkm/rendering/MapperGlyphVector.cxx +++ b/vtkm/rendering/MapperGlyphVector.cxx @@ -93,22 +93,22 @@ void MapperGlyphVector::RenderCells(const vtkm::cont::UnknownCellSet& cellset, { vtkm::Float32 minSize = baseSize - baseSize * this->ScaleDelta; vtkm::Float32 maxSize = baseSize + baseSize * this->ScaleDelta; - if (this->GlyphAssociation == vtkm::cont::Field::Association::Points) + if (this->Association == vtkm::cont::Field::Association::Points) { glyphExtractor.ExtractCoordinates(processedCoords, processedField, minSize, maxSize); } - else // this->GlyphAssociation == vtkm::cont::Field::Association::Cells + else // this->Association == vtkm::cont::Field::Association::Cells { glyphExtractor.ExtractCells(processedCellSet, processedField, minSize, maxSize); } } else { - if (this->GlyphAssociation == vtkm::cont::Field::Association::Points) + if (this->Association == vtkm::cont::Field::Association::Points) { glyphExtractor.ExtractCoordinates(processedCoords, processedField, baseSize); } - else // this->GlyphAssociation == vtkm::cont::Field::Association::Cells + else // this->Association == vtkm::cont::Field::Association::Cells { glyphExtractor.ExtractCells(processedCellSet, processedField, baseSize); } diff --git a/vtkm/rendering/MapperPoint.cxx b/vtkm/rendering/MapperPoint.cxx index 02bbbdfdb..3cbbd6f2d 100644 --- a/vtkm/rendering/MapperPoint.cxx +++ b/vtkm/rendering/MapperPoint.cxx @@ -28,26 +28,18 @@ namespace rendering struct MapperPoint::InternalsType { - vtkm::rendering::CanvasRayTracer* Canvas; + vtkm::rendering::CanvasRayTracer* Canvas = nullptr; vtkm::rendering::raytracing::RayTracer Tracer; vtkm::rendering::raytracing::Camera RayCamera; vtkm::rendering::raytracing::Ray Rays; - bool CompositeBackground; - vtkm::Float32 PointRadius; - bool UseNodes; - vtkm::Float32 PointDelta; - bool UseVariableRadius; + bool CompositeBackground = true; + vtkm::Float32 PointRadius = -1.f; + vtkm::cont::Field::Association Association = vtkm::cont::Field::Association::Points; + vtkm::Float32 PointDelta = 0.5f; + bool UseVariableRadius = false; VTKM_CONT - InternalsType() - : Canvas(nullptr) - , CompositeBackground(true) - , PointRadius(-1.f) - , UseNodes(true) - , PointDelta(0.5f) - , UseVariableRadius(false) - { - } + InternalsType() = default; }; MapperPoint::MapperPoint() @@ -78,13 +70,51 @@ vtkm::rendering::Canvas* MapperPoint::GetCanvas() const return this->Internals->Canvas; } +vtkm::cont::Field::Association MapperPoint::GetAssociation() const +{ + return this->Internals->Association; +} + +void MapperPoint::SetAssociation(cont::Field::Association association) +{ + switch (association) + { + case vtkm::cont::Field::Association::Cells: + case vtkm::cont::Field::Association::Points: + this->Internals->Association = association; + break; + default: + throw vtkm::cont::ErrorBadValue("Invalid point mapper association."); + } +} + +bool MapperPoint::GetUseCells() const +{ + return this->GetAssociation() == vtkm::cont::Field::Association::Cells; +} + +void MapperPoint::SetUseCells() +{ + this->SetAssociation(vtkm::cont::Field::Association::Cells); +} + +bool MapperPoint::GetUsePoints() const +{ + return this->GetAssociation() == vtkm::cont::Field::Association::Points; +} + +void MapperPoint::SetUsePoints() +{ + this->SetAssociation(vtkm::cont::Field::Association::Points); +} + void MapperPoint::UseCells() { - this->Internals->UseNodes = false; + this->SetUseCells(); } void MapperPoint::UseNodes() { - this->Internals->UseNodes = true; + this->SetUsePoints(); } void MapperPoint::SetRadius(const vtkm::Float32& radius) @@ -145,26 +175,30 @@ void MapperPoint::RenderCells(const vtkm::cont::UnknownCellSet& cellset, { vtkm::Float32 minRadius = baseRadius - baseRadius * this->Internals->PointDelta; vtkm::Float32 maxRadius = baseRadius + baseRadius * this->Internals->PointDelta; - if (this->Internals->UseNodes) + switch (this->Internals->Association) { - - sphereExtractor.ExtractCoordinates(coords, scalarField, minRadius, maxRadius); - } - else - { - sphereExtractor.ExtractCells(cellset, scalarField, minRadius, maxRadius); + case vtkm::cont::Field::Association::Points: + sphereExtractor.ExtractCoordinates(coords, scalarField, minRadius, maxRadius); + break; + case vtkm::cont::Field::Association::Cells: + sphereExtractor.ExtractCells(cellset, scalarField, minRadius, maxRadius); + break; + default: + throw vtkm::cont::ErrorInternal("Bad association."); } } else { - if (this->Internals->UseNodes) + switch (this->Internals->Association) { - - sphereExtractor.ExtractCoordinates(coords, baseRadius); - } - else - { - sphereExtractor.ExtractCells(cellset, baseRadius); + case vtkm::cont::Field::Association::Points: + sphereExtractor.ExtractCoordinates(coords, baseRadius); + break; + case vtkm::cont::Field::Association::Cells: + sphereExtractor.ExtractCells(cellset, baseRadius); + break; + default: + throw vtkm::cont::ErrorInternal("Bad association."); } } diff --git a/vtkm/rendering/MapperPoint.h b/vtkm/rendering/MapperPoint.h index beedbd96b..6d61a9a53 100644 --- a/vtkm/rendering/MapperPoint.h +++ b/vtkm/rendering/MapperPoint.h @@ -10,6 +10,7 @@ #ifndef vtk_m_rendering_MapperPoint_h #define vtk_m_rendering_MapperPoint_h +#include #include #include #include @@ -21,13 +22,11 @@ namespace vtkm namespace rendering { -/** - * \brief MapperPonts renders points from a cell set. - * This mapper can natively create points from - * vertex cell shapes as well as use the points - * defined by a coordinate system. - * - */ +/// @brief This mapper renders points from a cell set. +/// +/// This mapper can natively create points from +/// vertex cell shapes as well as use the points +/// defined by a coordinate system. class VTKM_RENDERING_EXPORT MapperPoint : public Mapper { public: @@ -38,38 +37,43 @@ public: void SetCanvas(vtkm::rendering::Canvas* canvas) override; virtual vtkm::rendering::Canvas* GetCanvas() const override; - /** - * \brief render points based on cell shape point - * - */ + /// @brief Specify the elements the points will be associated with. + /// + /// The point mapper will place visible points over locations specified by either the points + /// or the cells of a mesh. + virtual vtkm::cont::Field::Association GetAssociation() const; + /// @copydoc GetAssociation + virtual void SetAssociation(vtkm::cont::Field::Association association); + /// @copydoc GetAssociation + virtual bool GetUseCells() const; + /// @copydoc GetAssociation + virtual void SetUseCells(); + /// @copydoc GetAssociation + virtual bool GetUsePoints() const; + /// @copydoc GetAssociation + virtual void SetUsePoints(); + VTKM_DEPRECATED(2.2, "Use SetUseCells or SetAssociation.") void UseCells(); - /** - * \brief render points using the nodes of the mesh. - * This is the default. - */ + VTKM_DEPRECATED(2.2, "Use SetUsePoints or SetAssociation.") void UseNodes(); - /** - * \brief render points using a variable radius based on - * the scalar field. - * The default is false. - */ + /// + /// @brief Render points using a variable radius based on the scalar field. + /// + /// The default is false. void UseVariableRadius(bool useVariableRadius); - /** - * \brief Set a base raidus for all points. If a - * radius is never specified the default heuristic - * is used. - */ + /// @brief Set a base raidus for all points. + /// + /// If a radius is never specified the default heuristic is used. void SetRadius(const vtkm::Float32& radius); - /** - * \brief When using a variable raidus for all points, the - * radius delta controls how much larger and smaller - * radii become based on the scalar field. If the delta - * is 0 all points will have the same radius. If the delta - * is 0.5 then the max/min scalar values would have a radii - * of base +/- base * 0.5. - */ + + /// When using a variable raidus for all points, the + /// radius delta controls how much larger and smaller + /// radii become based on the scalar field. If the delta + /// is 0 all points will have the same radius. If the delta + /// is 0.5 then the max/min scalar values would have a radii + /// of base +/- base * 0.5. void SetRadiusDelta(const vtkm::Float32& delta); void RenderCells(const vtkm::cont::UnknownCellSet& cellset, diff --git a/vtkm/rendering/MapperQuad.h b/vtkm/rendering/MapperQuad.h index cb30d6877..e96fc17f3 100644 --- a/vtkm/rendering/MapperQuad.h +++ b/vtkm/rendering/MapperQuad.h @@ -22,7 +22,8 @@ namespace rendering { /** - * \brief MapperQuad renderers quad facess from a cell set via ray tracing. + * \brief A mapper that renderers quad faces from a cell set via ray tracing. + * * As opposed to breaking quads into two trianges, scalars are * interpolated using all 4 points of the quad resulting in more * accurate interpolation. diff --git a/vtkm/rendering/MapperRayTracer.h b/vtkm/rendering/MapperRayTracer.h index a3427a6e7..de32e0d14 100644 --- a/vtkm/rendering/MapperRayTracer.h +++ b/vtkm/rendering/MapperRayTracer.h @@ -21,6 +21,10 @@ namespace vtkm namespace rendering { +/// @brief Mapper to render surfaces using ray tracing. +/// +/// Provides a "standard" data mapper that uses ray tracing to render the surfaces +/// of `DataSet` objects. class VTKM_RENDERING_EXPORT MapperRayTracer : public Mapper { public: diff --git a/vtkm/rendering/MapperVolume.h b/vtkm/rendering/MapperVolume.h index fbee14192..1406ca246 100644 --- a/vtkm/rendering/MapperVolume.h +++ b/vtkm/rendering/MapperVolume.h @@ -19,6 +19,7 @@ namespace vtkm namespace rendering { +/// @brief Mapper that renders a volume as a translucent cloud. class VTKM_RENDERING_EXPORT MapperVolume : public Mapper { public: @@ -37,6 +38,11 @@ public: const vtkm::Range& scalarRange) override; vtkm::rendering::Mapper* NewCopy() const override; + /// @brief Specify how much space is between samples of rays that traverse the volume. + /// + /// The volume rendering ray caster finds the entry point of the ray through the volume + /// and then samples the volume along the direction of the ray at regular intervals. + /// This parameter specifies how far these samples occur. void SetSampleDistance(const vtkm::Float32 distance); void SetCompositeBackground(const bool compositeBackground); diff --git a/vtkm/rendering/MapperWireframer.h b/vtkm/rendering/MapperWireframer.h index 6ef6cb91a..5754d9523 100644 --- a/vtkm/rendering/MapperWireframer.h +++ b/vtkm/rendering/MapperWireframer.h @@ -25,6 +25,10 @@ namespace vtkm namespace rendering { +/// @brief Mapper that renders the edges of a mesh. +/// +/// Each edge in the mesh is rendered as a line, which provides a wireframe +/// representation of the data. class VTKM_RENDERING_EXPORT MapperWireframer : public Mapper { public: @@ -35,7 +39,13 @@ public: virtual vtkm::rendering::Canvas* GetCanvas() const override; virtual void SetCanvas(vtkm::rendering::Canvas* canvas) override; + /// @brief Specify whether to show interior edges. + /// + /// When rendering a 3D volume of data, the `MapperWireframer` can show + /// either the wireframe of the external surface of the data (the default) + /// or render the entire wireframe including the internal edges. bool GetShowInternalZones() const; + /// @copydoc GetShowInternalZones void SetShowInternalZones(bool showInternalZones); void SetCompositeBackground(bool on); diff --git a/vtkm/rendering/Scene.h b/vtkm/rendering/Scene.h index 00fdcf148..d5862d709 100644 --- a/vtkm/rendering/Scene.h +++ b/vtkm/rendering/Scene.h @@ -24,21 +24,28 @@ namespace vtkm namespace rendering { +/// @brief A simple collection of things to render. +/// +/// The `Scene` is a simple collection of `Actor` objects. class VTKM_RENDERING_EXPORT Scene { public: Scene(); + /// @brief Add an `Actor` to the scene. void AddActor(vtkm::rendering::Actor actor); + /// @brief Get one of the `Actor`s from the scene. const vtkm::rendering::Actor& GetActor(vtkm::IdComponent index) const; + /// @brief Get the number of `Actor`s in the scene. vtkm::IdComponent GetNumberOfActors() const; void Render(vtkm::rendering::Mapper& mapper, vtkm::rendering::Canvas& canvas, const vtkm::rendering::Camera& camera) const; + /// @brief The computed spatial bounds of combined data from all contained `Actor`s. vtkm::Bounds GetSpatialBounds() const; private: diff --git a/vtkm/rendering/View.h b/vtkm/rendering/View.h index e2361b432..e12ddc63c 100644 --- a/vtkm/rendering/View.h +++ b/vtkm/rendering/View.h @@ -27,6 +27,7 @@ namespace vtkm namespace rendering { +/// @brief The abstract class representing the view of a rendering scene. class VTKM_RENDERING_EXPORT View { struct InternalData; @@ -47,39 +48,54 @@ public: virtual ~View(); + /// @brief Specify the scene object holding the objects to render. VTKM_CONT const vtkm::rendering::Scene& GetScene() const; + /// @copydoc GetScene VTKM_CONT vtkm::rendering::Scene& GetScene(); + /// @copydoc GetScene VTKM_CONT void SetScene(const vtkm::rendering::Scene& scene); + /// @brief Specify the mapper object determining how objects are rendered. VTKM_CONT const vtkm::rendering::Mapper& GetMapper() const; + /// @copydoc GetMapper VTKM_CONT vtkm::rendering::Mapper& GetMapper(); + /// @brief Specify the canvas object that holds the buffer to render into. VTKM_CONT const vtkm::rendering::Canvas& GetCanvas() const; + /// @copydoc GetCanvas VTKM_CONT vtkm::rendering::Canvas& GetCanvas(); VTKM_CONT const vtkm::rendering::WorldAnnotator& GetWorldAnnotator() const; + /// @brief Specify the perspective from which to render a scene. VTKM_CONT const vtkm::rendering::Camera& GetCamera() const; + /// @copydoc GetCamera VTKM_CONT vtkm::rendering::Camera& GetCamera(); + /// @copydoc GetCamera VTKM_CONT void SetCamera(const vtkm::rendering::Camera& camera); + /// @brief Specify the color used where nothing is rendered. VTKM_CONT const vtkm::rendering::Color& GetBackgroundColor() const; - + /// @copydoc GetBackgroundColor VTKM_CONT void SetBackgroundColor(const vtkm::rendering::Color& color); + /// @brief @Specify the color of foreground elements. + /// + /// The foreground is typically used for annotation elements. + /// The foreground should contrast well with the background. VTKM_CONT void SetForegroundColor(const vtkm::rendering::Color& color); @@ -92,12 +108,14 @@ public: VTKM_CONT void SetRenderAnnotationsEnabled(bool val) { this->RenderAnnotationsEnabled = val; } VTKM_CONT bool GetRenderAnnotationsEnabled() const { return this->RenderAnnotationsEnabled; } + /// @brief Render a scene and store the result in the canvas' buffers. virtual void Paint() = 0; virtual void RenderScreenAnnotations() = 0; virtual void RenderWorldAnnotations() = 0; void RenderAnnotations(); + /// @copydoc vtkm::rendering::Canvas::SaveAs void SaveAs(const std::string& fileName) const; VTKM_CONT diff --git a/vtkm/rendering/View1D.h b/vtkm/rendering/View1D.h index 6366d0cc7..c4a3e9ca1 100644 --- a/vtkm/rendering/View1D.h +++ b/vtkm/rendering/View1D.h @@ -19,6 +19,9 @@ namespace vtkm namespace rendering { +/// @brief A view for a 1D data set. +/// +/// 1D data are rendered as an X-Y plot with the values shone on the Y axis. class VTKM_RENDERING_EXPORT View1D : public vtkm::rendering::View { public: @@ -44,12 +47,14 @@ public: void DisableLegend(); void SetLegendLabelColor(vtkm::rendering::Color c) { this->Legend.SetLabelColor(c); } + /// @brief Specify whether log scaling should be used on the X axis. void SetLogX(bool l) { this->GetMapper().SetLogarithmX(l); this->LogX = l; } + /// @brief Specify whether log scaling should be used on the Y axis. void SetLogY(bool l) { this->GetMapper().SetLogarithmY(l); diff --git a/vtkm/rendering/View2D.h b/vtkm/rendering/View2D.h index 5e358931f..c29ed5b5e 100644 --- a/vtkm/rendering/View2D.h +++ b/vtkm/rendering/View2D.h @@ -20,6 +20,9 @@ namespace vtkm namespace rendering { +/// @brief A view for a 3D data set. +/// +/// 2D data are rendered directly on the X-Y plane. class VTKM_RENDERING_EXPORT View2D : public vtkm::rendering::View { public: diff --git a/vtkm/rendering/View3D.h b/vtkm/rendering/View3D.h index 4246b670d..59a9a2feb 100644 --- a/vtkm/rendering/View3D.h +++ b/vtkm/rendering/View3D.h @@ -21,6 +21,7 @@ namespace vtkm namespace rendering { +/// @brief A view for a 3D data set. class VTKM_RENDERING_EXPORT View3D : public vtkm::rendering::View { public: diff --git a/vtkm/rendering/testlib/RenderTest.cxx b/vtkm/rendering/testlib/RenderTest.cxx index 894d9d999..366532263 100644 --- a/vtkm/rendering/testlib/RenderTest.cxx +++ b/vtkm/rendering/testlib/RenderTest.cxx @@ -114,7 +114,7 @@ void SetupMapper(vtkm::rendering::MapperPoint& mapper, mapper.SetRadiusDelta(0.5); if (options.RenderCells) { - mapper.UseCells(); + mapper.SetUseCells(); } }