Merge branch 'isosurface-for-sprint' into 'master'
Isosurface for sprint See merge request !150
This commit is contained in:
commit
9cb00d9048
@ -27,6 +27,8 @@ set(headers
|
||||
CellAverage.h
|
||||
Clip.h
|
||||
ExternalFaces.h
|
||||
IsosurfaceUniformGrid.h
|
||||
MarchingCubesDataTables.h
|
||||
PointElevation.h
|
||||
VertexClustering.h
|
||||
)
|
||||
|
295
vtkm/worklet/IsosurfaceUniformGrid.h
Normal file
295
vtkm/worklet/IsosurfaceUniformGrid.h
Normal file
@ -0,0 +1,295 @@
|
||||
//============================================================================
|
||||
// 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.
|
||||
//
|
||||
// Copyright 2014 Sandia Corporation.
|
||||
// Copyright 2014 UT-Battelle, LLC.
|
||||
// Copyright 2014 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
||||
// the U.S. Government retains certain rights in this software.
|
||||
//
|
||||
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
|
||||
// Laboratory (LANL), the U.S. Government retains certain rights in
|
||||
// this software.
|
||||
//============================================================================
|
||||
|
||||
#ifndef vtk_m_worklet_IsosurfaceUniformGrid_h
|
||||
#define vtk_m_worklet_IsosurfaceUniformGrid_h
|
||||
|
||||
#include <vtkm/cont/DeviceAdapter.h>
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
#include <vtkm/cont/ArrayHandleCounting.h>
|
||||
#include <vtkm/cont/DynamicArrayHandle.h>
|
||||
#include <vtkm/worklet/DispatcherMapField.h>
|
||||
#include <vtkm/worklet/WorkletMapField.h>
|
||||
#include <vtkm/Pair.h>
|
||||
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
#include <vtkm/cont/Field.h>
|
||||
#include <vtkm/worklet/DispatcherMapTopology.h>
|
||||
#include <vtkm/worklet/WorkletMapTopology.h>
|
||||
#include <vtkm/VectorAnalysis.h>
|
||||
|
||||
#include "MarchingCubesDataTables.h"
|
||||
|
||||
namespace vtkm {
|
||||
namespace worklet {
|
||||
|
||||
/// \brief Compute the isosurface for a uniform grid data set
|
||||
template <typename FieldType, typename DeviceAdapter>
|
||||
class IsosurfaceFilterUniformGrid
|
||||
{
|
||||
public:
|
||||
|
||||
class ClassifyCell : public vtkm::worklet::WorkletMapTopologyPointToCell
|
||||
{
|
||||
public:
|
||||
typedef void ControlSignature(FieldInFrom<Scalar> inNodes,
|
||||
TopologyIn topology,
|
||||
FieldOut<IdType> outNumVertices);
|
||||
typedef void ExecutionSignature(_1, _3);
|
||||
typedef _2 InputDomain;
|
||||
|
||||
typedef vtkm::cont::ArrayHandle<vtkm::Id> IdArrayHandle;
|
||||
typedef typename IdArrayHandle::ExecutionTypes<DeviceAdapter>::PortalConst IdPortalType;
|
||||
IdPortalType VertexTable;
|
||||
vtkm::Float32 Isovalue;
|
||||
|
||||
VTKM_CONT_EXPORT
|
||||
ClassifyCell(IdPortalType vTable, float isovalue) :
|
||||
VertexTable(vTable),
|
||||
Isovalue(isovalue)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename InPointVecType>
|
||||
VTKM_EXEC_EXPORT
|
||||
void operator()(const InPointVecType &pointValues,
|
||||
vtkm::Id& numVertices) const
|
||||
{
|
||||
vtkm::Id caseNumber = (pointValues[0] > this->Isovalue);
|
||||
caseNumber += (pointValues[1] > this->Isovalue)*2;
|
||||
caseNumber += (pointValues[2] > this->Isovalue)*4;
|
||||
caseNumber += (pointValues[3] > this->Isovalue)*8;
|
||||
caseNumber += (pointValues[4] > this->Isovalue)*16;
|
||||
caseNumber += (pointValues[5] > this->Isovalue)*32;
|
||||
caseNumber += (pointValues[6] > this->Isovalue)*64;
|
||||
caseNumber += (pointValues[7] > this->Isovalue)*128;
|
||||
numVertices = this->VertexTable.Get(caseNumber) / 3;
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Compute isosurface vertices and scalars
|
||||
class IsoSurfaceGenerate : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
typedef void ControlSignature(FieldIn<IdType> inputCellId,
|
||||
FieldIn<IdType> inputIteration);
|
||||
typedef void ExecutionSignature(WorkIndex, _1, _2);
|
||||
typedef _1 InputDomain;
|
||||
|
||||
const float Isovalue;
|
||||
vtkm::Id xdim, ydim, zdim;
|
||||
const float xmin, ymin, zmin, xmax, ymax, zmax;
|
||||
|
||||
typedef typename vtkm::cont::ArrayHandle<FieldType>::template ExecutionTypes<DeviceAdapter>::PortalConst FieldPortalType;
|
||||
FieldPortalType Field, Source;
|
||||
|
||||
typedef typename vtkm::cont::ArrayHandle<FieldType>::template ExecutionTypes<DeviceAdapter>::Portal OutputPortalType;
|
||||
OutputPortalType Scalars;
|
||||
|
||||
typedef typename vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3> >::template ExecutionTypes<DeviceAdapter>::Portal VectorPortalType;
|
||||
VectorPortalType Vertices;
|
||||
|
||||
typedef typename vtkm::cont::ArrayHandle<vtkm::Id> IdArrayHandle;
|
||||
typedef typename IdArrayHandle::ExecutionTypes<DeviceAdapter>::PortalConst IdPortalType;
|
||||
IdPortalType TriTable;
|
||||
|
||||
const vtkm::Id cellsPerLayer, pointsPerLayer;
|
||||
|
||||
template<typename U, typename W, typename X>
|
||||
VTKM_CONT_EXPORT
|
||||
IsoSurfaceGenerate(const float ivalue, const vtkm::Id3 dims, IdPortalType triTablePortal,
|
||||
const U & field, const U & source, const W & vertices, const X & scalars) :
|
||||
Isovalue(ivalue),
|
||||
xdim(dims[0]), ydim(dims[1]), zdim(dims[2]),
|
||||
xmin(-1), ymin(-1), zmin(-1), xmax(1), ymax(1), zmax(1),
|
||||
Field( field.PrepareForInput( DeviceAdapter() ) ),
|
||||
Source( source.PrepareForInput( DeviceAdapter() ) ),
|
||||
Scalars(scalars),
|
||||
Vertices(vertices),
|
||||
TriTable(triTablePortal),
|
||||
cellsPerLayer((xdim-1) * (ydim-1)),
|
||||
pointsPerLayer (xdim*ydim)
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_EXEC_EXPORT
|
||||
void operator()(vtkm::Id outputCellId, vtkm::Id inputCellId, vtkm::Id inputLowerBounds) const
|
||||
{
|
||||
// Get data for this cell
|
||||
const int verticesForEdge[] = { 0, 1, 1, 2, 3, 2, 0, 3,
|
||||
4, 5, 5, 6, 7, 6, 4, 7,
|
||||
0, 4, 1, 5, 2, 6, 3, 7 };
|
||||
|
||||
const vtkm::Id x = inputCellId % (xdim - 1);
|
||||
const vtkm::Id y = (inputCellId / (xdim - 1)) % (ydim -1);
|
||||
const vtkm::Id z = inputCellId / cellsPerLayer;
|
||||
|
||||
// Compute indices for the eight vertices of this cell
|
||||
const vtkm::Id i0 = x + y*xdim + z * pointsPerLayer;
|
||||
const vtkm::Id i1 = i0 + 1;
|
||||
const vtkm::Id i2 = i0 + 1 + xdim;
|
||||
const vtkm::Id i3 = i0 + xdim;
|
||||
const vtkm::Id i4 = i0 + pointsPerLayer;
|
||||
const vtkm::Id i5 = i1 + pointsPerLayer;
|
||||
const vtkm::Id i6 = i2 + pointsPerLayer;
|
||||
const vtkm::Id i7 = i3 + pointsPerLayer;
|
||||
|
||||
// Get the field values at these eight vertices
|
||||
float f[8];
|
||||
f[0] = this->Field.Get(i0);
|
||||
f[1] = this->Field.Get(i1);
|
||||
f[2] = this->Field.Get(i2);
|
||||
f[3] = this->Field.Get(i3);
|
||||
f[4] = this->Field.Get(i4);
|
||||
f[5] = this->Field.Get(i5);
|
||||
f[6] = this->Field.Get(i6);
|
||||
f[7] = this->Field.Get(i7);
|
||||
|
||||
// Compute the Marching Cubes case number for this cell
|
||||
unsigned int cubeindex = 0;
|
||||
cubeindex += (f[0] > this->Isovalue);
|
||||
cubeindex += (f[1] > this->Isovalue)*2;
|
||||
cubeindex += (f[2] > this->Isovalue)*4;
|
||||
cubeindex += (f[3] > this->Isovalue)*8;
|
||||
cubeindex += (f[4] > this->Isovalue)*16;
|
||||
cubeindex += (f[5] > this->Isovalue)*32;
|
||||
cubeindex += (f[6] > this->Isovalue)*64;
|
||||
cubeindex += (f[7] > this->Isovalue)*128;
|
||||
|
||||
// Compute the coordinates of the uniform regular grid at each of the cell's eight vertices
|
||||
vtkm::Vec<FieldType, 3> p[8];
|
||||
|
||||
// Get the scalar source values at the eight vertices
|
||||
float s[8];
|
||||
s[0] = this->Source.Get(i0);
|
||||
s[1] = this->Source.Get(i1);
|
||||
s[2] = this->Source.Get(i2);
|
||||
s[3] = this->Source.Get(i3);
|
||||
s[4] = this->Source.Get(i4);
|
||||
s[5] = this->Source.Get(i5);
|
||||
s[6] = this->Source.Get(i6);
|
||||
s[7] = this->Source.Get(i7);
|
||||
|
||||
// Interpolate for vertex positions and associated scalar values
|
||||
const vtkm::Id inputIteration = (outputCellId - inputLowerBounds);
|
||||
const vtkm::Id outputVertId = outputCellId * 3;
|
||||
const vtkm::Id cellOffset = static_cast<vtkm::Id>(cubeindex*16) + (inputIteration * 3);
|
||||
for (int v = 0; v < 3; v++)
|
||||
{
|
||||
const vtkm::Id edge = this->TriTable.Get(cellOffset + v);
|
||||
const int v0 = verticesForEdge[2*edge];
|
||||
const int v1 = verticesForEdge[2*edge + 1];
|
||||
const float t = (this->Isovalue - f[v0]) / (f[v1] - f[v0]);
|
||||
|
||||
this->Vertices.Set(outputVertId + v, vtkm::Lerp(p[v0], p[v1], t));
|
||||
this->Scalars.Set(outputVertId + v, vtkm::Lerp(s[v0], s[v1], t));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
IsosurfaceFilterUniformGrid(const vtkm::Id3 &vdims,
|
||||
const vtkm::cont::DataSet &dataSet) :
|
||||
VDims(vdims),
|
||||
DataSet(dataSet)
|
||||
{
|
||||
}
|
||||
|
||||
vtkm::Id3 VDims;
|
||||
vtkm::cont::DataSet DataSet;
|
||||
|
||||
template<typename IsoField, typename CoordinateType>
|
||||
void Run(const float &isovalue,
|
||||
IsoField isoField,
|
||||
vtkm::cont::ArrayHandle< vtkm::Vec<CoordinateType,3> > &verticesArray,
|
||||
vtkm::cont::ArrayHandle<FieldType> &scalarsArray)
|
||||
{
|
||||
typedef typename vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter> DeviceAlgorithms;
|
||||
|
||||
// Set up the Marching Cubes case tables
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> vertexTableArray =
|
||||
vtkm::cont::make_ArrayHandle(vtkm::worklet::internal::numVerticesTable,
|
||||
256);
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> triangleTableArray =
|
||||
vtkm::cont::make_ArrayHandle(vtkm::worklet::internal::triTable,
|
||||
256*16);
|
||||
|
||||
// Call the ClassifyCell functor to compute the Marching Cubes case numbers
|
||||
// for each cell, and the number of vertices to be generated
|
||||
ClassifyCell classifyCell(vertexTableArray.PrepareForInput(DeviceAdapter()),
|
||||
isovalue);
|
||||
|
||||
typedef typename vtkm::worklet::DispatcherMapTopology<
|
||||
ClassifyCell,
|
||||
DeviceAdapter> ClassifyCellDispatcher;
|
||||
ClassifyCellDispatcher classifyCellDispatcher(classifyCell);
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> numOutputTrisPerCell;
|
||||
classifyCellDispatcher.Invoke( isoField,
|
||||
this->DataSet.GetCellSet(0),
|
||||
numOutputTrisPerCell);
|
||||
|
||||
// Compute the number of valid input cells and those ids
|
||||
const vtkm::Id numOutputCells = DeviceAlgorithms::ScanInclusive(numOutputTrisPerCell,
|
||||
numOutputTrisPerCell);
|
||||
|
||||
// Terminate if no cells has triangles left
|
||||
if (numOutputCells == 0) return;
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> validCellIndicesArray, inputCellIterationNumber;
|
||||
vtkm::cont::ArrayHandleCounting<vtkm::Id> validCellCountImplicitArray(0, numOutputCells);
|
||||
DeviceAlgorithms::UpperBounds(numOutputTrisPerCell,
|
||||
validCellCountImplicitArray,
|
||||
validCellIndicesArray);
|
||||
numOutputTrisPerCell.ReleaseResources();
|
||||
|
||||
// Compute for each output triangle what iteration of the input cell generates it
|
||||
DeviceAlgorithms::LowerBounds(validCellIndicesArray,
|
||||
validCellIndicesArray,
|
||||
inputCellIterationNumber);
|
||||
|
||||
// Generate a single triangle per cell
|
||||
const vtkm::Id numTotalVertices = numOutputCells * 3;
|
||||
|
||||
//todo this needs to change so that we don't presume the storage type
|
||||
vtkm::cont::ArrayHandle<FieldType> field;
|
||||
field = isoField.CastToArrayHandle(FieldType(), VTKM_DEFAULT_STORAGE_TAG());
|
||||
|
||||
|
||||
IsoSurfaceGenerate isosurface(isovalue,
|
||||
this->VDims,
|
||||
triangleTableArray.PrepareForInput(DeviceAdapter()),
|
||||
field,
|
||||
field,
|
||||
verticesArray.PrepareForOutput(numTotalVertices, DeviceAdapter()),
|
||||
scalarsArray.PrepareForOutput(numTotalVertices, DeviceAdapter())
|
||||
);
|
||||
|
||||
typedef typename vtkm::worklet::DispatcherMapField< IsoSurfaceGenerate,
|
||||
DeviceAdapter> IsoSurfaceDispatcher;
|
||||
IsoSurfaceDispatcher isosurfaceDispatcher(isosurface);
|
||||
isosurfaceDispatcher.Invoke(validCellIndicesArray, inputCellIterationNumber);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace vtkm::worklet
|
||||
|
||||
#endif // vtk_m_worklet_IsosurfaceUniformGrid_h
|
554
vtkm/worklet/MarchingCubesDataTables.h
Executable file
554
vtkm/worklet/MarchingCubesDataTables.h
Executable file
@ -0,0 +1,554 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// Copyright 2015 Sandia Corporation.
|
||||
// Copyright 2015 UT-Battelle, LLC.
|
||||
// Copyright 2015 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
||||
// the U.S. Government retains certain rights in this software.
|
||||
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
|
||||
// Laboratory (LANL), the U.S. Government retains certain rights in
|
||||
// this software.
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include <vtkm/Types.h>
|
||||
|
||||
namespace vtkm {
|
||||
namespace worklet {
|
||||
|
||||
namespace internal {
|
||||
|
||||
const vtkm::Id numVerticesTable[256] = {
|
||||
0,
|
||||
3,
|
||||
3,
|
||||
6,
|
||||
3,
|
||||
6,
|
||||
6,
|
||||
9,
|
||||
3,
|
||||
6,
|
||||
6,
|
||||
9,
|
||||
6,
|
||||
9,
|
||||
9,
|
||||
6,
|
||||
3,
|
||||
6,
|
||||
6,
|
||||
9,
|
||||
6,
|
||||
9,
|
||||
9,
|
||||
12,
|
||||
6,
|
||||
9,
|
||||
9,
|
||||
12,
|
||||
9,
|
||||
12,
|
||||
12,
|
||||
9,
|
||||
3,
|
||||
6,
|
||||
6,
|
||||
9,
|
||||
6,
|
||||
9,
|
||||
9,
|
||||
12,
|
||||
6,
|
||||
9,
|
||||
9,
|
||||
12,
|
||||
9,
|
||||
12,
|
||||
12,
|
||||
9,
|
||||
6,
|
||||
9,
|
||||
9,
|
||||
6,
|
||||
9,
|
||||
12,
|
||||
12,
|
||||
9,
|
||||
9,
|
||||
12,
|
||||
12,
|
||||
9,
|
||||
12,
|
||||
15,
|
||||
15,
|
||||
6,
|
||||
3,
|
||||
6,
|
||||
6,
|
||||
9,
|
||||
6,
|
||||
9,
|
||||
9,
|
||||
12,
|
||||
6,
|
||||
9,
|
||||
9,
|
||||
12,
|
||||
9,
|
||||
12,
|
||||
12,
|
||||
9,
|
||||
6,
|
||||
9,
|
||||
9,
|
||||
12,
|
||||
9,
|
||||
12,
|
||||
12,
|
||||
15,
|
||||
9,
|
||||
12,
|
||||
12,
|
||||
15,
|
||||
12,
|
||||
15,
|
||||
15,
|
||||
12,
|
||||
6,
|
||||
9,
|
||||
9,
|
||||
12,
|
||||
9,
|
||||
12,
|
||||
6,
|
||||
9,
|
||||
9,
|
||||
12,
|
||||
12,
|
||||
15,
|
||||
12,
|
||||
15,
|
||||
9,
|
||||
6,
|
||||
9,
|
||||
12,
|
||||
12,
|
||||
9,
|
||||
12,
|
||||
15,
|
||||
9,
|
||||
6,
|
||||
12,
|
||||
15,
|
||||
15,
|
||||
12,
|
||||
15,
|
||||
6,
|
||||
12,
|
||||
3,
|
||||
3,
|
||||
6,
|
||||
6,
|
||||
9,
|
||||
6,
|
||||
9,
|
||||
9,
|
||||
12,
|
||||
6,
|
||||
9,
|
||||
9,
|
||||
12,
|
||||
9,
|
||||
12,
|
||||
12,
|
||||
9,
|
||||
6,
|
||||
9,
|
||||
9,
|
||||
12,
|
||||
9,
|
||||
12,
|
||||
12,
|
||||
15,
|
||||
9,
|
||||
6,
|
||||
12,
|
||||
9,
|
||||
12,
|
||||
9,
|
||||
15,
|
||||
6,
|
||||
6,
|
||||
9,
|
||||
9,
|
||||
12,
|
||||
9,
|
||||
12,
|
||||
12,
|
||||
15,
|
||||
9,
|
||||
12,
|
||||
12,
|
||||
15,
|
||||
12,
|
||||
15,
|
||||
15,
|
||||
12,
|
||||
9,
|
||||
12,
|
||||
12,
|
||||
9,
|
||||
12,
|
||||
15,
|
||||
15,
|
||||
12,
|
||||
12,
|
||||
9,
|
||||
15,
|
||||
6,
|
||||
15,
|
||||
12,
|
||||
6,
|
||||
3,
|
||||
6,
|
||||
9,
|
||||
9,
|
||||
12,
|
||||
9,
|
||||
12,
|
||||
12,
|
||||
15,
|
||||
9,
|
||||
12,
|
||||
12,
|
||||
15,
|
||||
6,
|
||||
9,
|
||||
9,
|
||||
6,
|
||||
9,
|
||||
12,
|
||||
12,
|
||||
15,
|
||||
12,
|
||||
15,
|
||||
15,
|
||||
6,
|
||||
12,
|
||||
9,
|
||||
15,
|
||||
12,
|
||||
9,
|
||||
6,
|
||||
12,
|
||||
3,
|
||||
9,
|
||||
12,
|
||||
12,
|
||||
15,
|
||||
12,
|
||||
15,
|
||||
9,
|
||||
12,
|
||||
12,
|
||||
15,
|
||||
15,
|
||||
6,
|
||||
9,
|
||||
12,
|
||||
6,
|
||||
3,
|
||||
6,
|
||||
9,
|
||||
9,
|
||||
6,
|
||||
9,
|
||||
12,
|
||||
6,
|
||||
3,
|
||||
9,
|
||||
6,
|
||||
12,
|
||||
3,
|
||||
6,
|
||||
3,
|
||||
3,
|
||||
0,
|
||||
};
|
||||
|
||||
|
||||
const vtkm::Id triTable[256*16] =
|
||||
{
|
||||
#define X -1
|
||||
X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X,
|
||||
0, 8, 3, X, X, X, X, X, X, X, X, X, X, X, X, X,
|
||||
0, 1, 9, X, X, X, X, X, X, X, X, X, X, X, X, X,
|
||||
1, 8, 3, 9, 8, 1, X, X, X, X, X, X, X, X, X, X,
|
||||
1, 2, 10, X, X, X, X, X, X, X, X, X, X, X, X, X,
|
||||
0, 8, 3, 1, 2, 10, X, X, X, X, X, X, X, X, X, X,
|
||||
9, 2, 10, 0, 2, 9, X, X, X, X, X, X, X, X, X, X,
|
||||
2, 8, 3, 2, 10, 8, 10, 9, 8, X, X, X, X, X, X, X,
|
||||
3, 11, 2, X, X, X, X, X, X, X, X, X, X, X, X, X,
|
||||
0, 11, 2, 8, 11, 0, X, X, X, X, X, X, X, X, X, X,
|
||||
1, 9, 0, 2, 3, 11, X, X, X, X, X, X, X, X, X, X,
|
||||
1, 11, 2, 1, 9, 11, 9, 8, 11, X, X, X, X, X, X, X,
|
||||
3, 10, 1, 11, 10, 3, X, X, X, X, X, X, X, X, X, X,
|
||||
0, 10, 1, 0, 8, 10, 8, 11, 10, X, X, X, X, X, X, X,
|
||||
3, 9, 0, 3, 11, 9, 11, 10, 9, X, X, X, X, X, X, X,
|
||||
9, 8, 10, 10, 8, 11, X, X, X, X, X, X, X, X, X, X,
|
||||
4, 7, 8, X, X, X, X, X, X, X, X, X, X, X, X, X,
|
||||
4, 3, 0, 7, 3, 4, X, X, X, X, X, X, X, X, X, X,
|
||||
0, 1, 9, 8, 4, 7, X, X, X, X, X, X, X, X, X, X,
|
||||
4, 1, 9, 4, 7, 1, 7, 3, 1, X, X, X, X, X, X, X,
|
||||
1, 2, 10, 8, 4, 7, X, X, X, X, X, X, X, X, X, X,
|
||||
3, 4, 7, 3, 0, 4, 1, 2, 10, X, X, X, X, X, X, X,
|
||||
9, 2, 10, 9, 0, 2, 8, 4, 7, X, X, X, X, X, X, X,
|
||||
2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, X, X, X, X,
|
||||
8, 4, 7, 3, 11, 2, X, X, X, X, X, X, X, X, X, X,
|
||||
11, 4, 7, 11, 2, 4, 2, 0, 4, X, X, X, X, X, X, X,
|
||||
9, 0, 1, 8, 4, 7, 2, 3, 11, X, X, X, X, X, X, X,
|
||||
4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, X, X, X, X,
|
||||
3, 10, 1, 3, 11, 10, 7, 8, 4, X, X, X, X, X, X, X,
|
||||
1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, X, X, X, X,
|
||||
4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, X, X, X, X,
|
||||
4, 7, 11, 4, 11, 9, 9, 11, 10, X, X, X, X, X, X, X,
|
||||
9, 5, 4, X, X, X, X, X, X, X, X, X, X, X, X, X,
|
||||
9, 5, 4, 0, 8, 3, X, X, X, X, X, X, X, X, X, X,
|
||||
0, 5, 4, 1, 5, 0, X, X, X, X, X, X, X, X, X, X,
|
||||
8, 5, 4, 8, 3, 5, 3, 1, 5, X, X, X, X, X, X, X,
|
||||
1, 2, 10, 9, 5, 4, X, X, X, X, X, X, X, X, X, X,
|
||||
3, 0, 8, 1, 2, 10, 4, 9, 5, X, X, X, X, X, X, X,
|
||||
5, 2, 10, 5, 4, 2, 4, 0, 2, X, X, X, X, X, X, X,
|
||||
2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, X, X, X, X,
|
||||
9, 5, 4, 2, 3, 11, X, X, X, X, X, X, X, X, X, X,
|
||||
0, 11, 2, 0, 8, 11, 4, 9, 5, X, X, X, X, X, X, X,
|
||||
0, 5, 4, 0, 1, 5, 2, 3, 11, X, X, X, X, X, X, X,
|
||||
2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, X, X, X, X,
|
||||
10, 3, 11, 10, 1, 3, 9, 5, 4, X, X, X, X, X, X, X,
|
||||
4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, X, X, X, X,
|
||||
5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, X, X, X, X,
|
||||
5, 4, 8, 5, 8, 10, 10, 8, 11, X, X, X, X, X, X, X,
|
||||
9, 7, 8, 5, 7, 9, X, X, X, X, X, X, X, X, X, X,
|
||||
9, 3, 0, 9, 5, 3, 5, 7, 3, X, X, X, X, X, X, X,
|
||||
0, 7, 8, 0, 1, 7, 1, 5, 7, X, X, X, X, X, X, X,
|
||||
1, 5, 3, 3, 5, 7, X, X, X, X, X, X, X, X, X, X,
|
||||
9, 7, 8, 9, 5, 7, 10, 1, 2, X, X, X, X, X, X, X,
|
||||
10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, X, X, X, X,
|
||||
8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, X, X, X, X,
|
||||
2, 10, 5, 2, 5, 3, 3, 5, 7, X, X, X, X, X, X, X,
|
||||
7, 9, 5, 7, 8, 9, 3, 11, 2, X, X, X, X, X, X, X,
|
||||
9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, X, X, X, X,
|
||||
2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, X, X, X, X,
|
||||
11, 2, 1, 11, 1, 7, 7, 1, 5, X, X, X, X, X, X, X,
|
||||
9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, X, X, X, X,
|
||||
5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, X,
|
||||
11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, X,
|
||||
11, 10, 5, 7, 11, 5, X, X, X, X, X, X, X, X, X, X,
|
||||
10, 6, 5, X, X, X, X, X, X, X, X, X, X, X, X, X,
|
||||
0, 8, 3, 5, 10, 6, X, X, X, X, X, X, X, X, X, X,
|
||||
9, 0, 1, 5, 10, 6, X, X, X, X, X, X, X, X, X, X,
|
||||
1, 8, 3, 1, 9, 8, 5, 10, 6, X, X, X, X, X, X, X,
|
||||
1, 6, 5, 2, 6, 1, X, X, X, X, X, X, X, X, X, X,
|
||||
1, 6, 5, 1, 2, 6, 3, 0, 8, X, X, X, X, X, X, X,
|
||||
9, 6, 5, 9, 0, 6, 0, 2, 6, X, X, X, X, X, X, X,
|
||||
5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, X, X, X, X,
|
||||
2, 3, 11, 10, 6, 5, X, X, X, X, X, X, X, X, X, X,
|
||||
11, 0, 8, 11, 2, 0, 10, 6, 5, X, X, X, X, X, X, X,
|
||||
0, 1, 9, 2, 3, 11, 5, 10, 6, X, X, X, X, X, X, X,
|
||||
5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, X, X, X, X,
|
||||
6, 3, 11, 6, 5, 3, 5, 1, 3, X, X, X, X, X, X, X,
|
||||
0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, X, X, X, X,
|
||||
3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, X, X, X, X,
|
||||
6, 5, 9, 6, 9, 11, 11, 9, 8, X, X, X, X, X, X, X,
|
||||
5, 10, 6, 4, 7, 8, X, X, X, X, X, X, X, X, X, X,
|
||||
4, 3, 0, 4, 7, 3, 6, 5, 10, X, X, X, X, X, X, X,
|
||||
1, 9, 0, 5, 10, 6, 8, 4, 7, X, X, X, X, X, X, X,
|
||||
10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, X, X, X, X,
|
||||
6, 1, 2, 6, 5, 1, 4, 7, 8, X, X, X, X, X, X, X,
|
||||
1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, X, X, X, X,
|
||||
8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, X, X, X, X,
|
||||
7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, X,
|
||||
3, 11, 2, 7, 8, 4, 10, 6, 5, X, X, X, X, X, X, X,
|
||||
5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, X, X, X, X,
|
||||
0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, X, X, X, X,
|
||||
9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, X,
|
||||
8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, X, X, X, X,
|
||||
5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, X,
|
||||
0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, X,
|
||||
6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, X, X, X, X,
|
||||
10, 4, 9, 6, 4, 10, X, X, X, X, X, X, X, X, X, X,
|
||||
4, 10, 6, 4, 9, 10, 0, 8, 3, X, X, X, X, X, X, X,
|
||||
10, 0, 1, 10, 6, 0, 6, 4, 0, X, X, X, X, X, X, X,
|
||||
8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, X, X, X, X,
|
||||
1, 4, 9, 1, 2, 4, 2, 6, 4, X, X, X, X, X, X, X,
|
||||
3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, X, X, X, X,
|
||||
0, 2, 4, 4, 2, 6, X, X, X, X, X, X, X, X, X, X,
|
||||
8, 3, 2, 8, 2, 4, 4, 2, 6, X, X, X, X, X, X, X,
|
||||
10, 4, 9, 10, 6, 4, 11, 2, 3, X, X, X, X, X, X, X,
|
||||
0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, X, X, X, X,
|
||||
3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, X, X, X, X,
|
||||
6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, X,
|
||||
9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, X, X, X, X,
|
||||
8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, X,
|
||||
3, 11, 6, 3, 6, 0, 0, 6, 4, X, X, X, X, X, X, X,
|
||||
6, 4, 8, 11, 6, 8, X, X, X, X, X, X, X, X, X, X,
|
||||
7, 10, 6, 7, 8, 10, 8, 9, 10, X, X, X, X, X, X, X,
|
||||
0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, X, X, X, X,
|
||||
10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, X, X, X, X,
|
||||
10, 6, 7, 10, 7, 1, 1, 7, 3, X, X, X, X, X, X, X,
|
||||
1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, X, X, X, X,
|
||||
2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, X,
|
||||
7, 8, 0, 7, 0, 6, 6, 0, 2, X, X, X, X, X, X, X,
|
||||
7, 3, 2, 6, 7, 2, X, X, X, X, X, X, X, X, X, X,
|
||||
2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, X, X, X, X,
|
||||
2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, X,
|
||||
1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, X,
|
||||
11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, X, X, X, X,
|
||||
8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, X,
|
||||
0, 9, 1, 11, 6, 7, X, X, X, X, X, X, X, X, X, X,
|
||||
7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, X, X, X, X,
|
||||
7, 11, 6, X, X, X, X, X, X, X, X, X, X, X, X, X,
|
||||
7, 6, 11, X, X, X, X, X, X, X, X, X, X, X, X, X,
|
||||
3, 0, 8, 11, 7, 6, X, X, X, X, X, X, X, X, X, X,
|
||||
0, 1, 9, 11, 7, 6, X, X, X, X, X, X, X, X, X, X,
|
||||
8, 1, 9, 8, 3, 1, 11, 7, 6, X, X, X, X, X, X, X,
|
||||
10, 1, 2, 6, 11, 7, X, X, X, X, X, X, X, X, X, X,
|
||||
1, 2, 10, 3, 0, 8, 6, 11, 7, X, X, X, X, X, X, X,
|
||||
2, 9, 0, 2, 10, 9, 6, 11, 7, X, X, X, X, X, X, X,
|
||||
6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, X, X, X, X,
|
||||
7, 2, 3, 6, 2, 7, X, X, X, X, X, X, X, X, X, X,
|
||||
7, 0, 8, 7, 6, 0, 6, 2, 0, X, X, X, X, X, X, X,
|
||||
2, 7, 6, 2, 3, 7, 0, 1, 9, X, X, X, X, X, X, X,
|
||||
1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, X, X, X, X,
|
||||
10, 7, 6, 10, 1, 7, 1, 3, 7, X, X, X, X, X, X, X,
|
||||
10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, X, X, X, X,
|
||||
0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, X, X, X, X,
|
||||
7, 6, 10, 7, 10, 8, 8, 10, 9, X, X, X, X, X, X, X,
|
||||
6, 8, 4, 11, 8, 6, X, X, X, X, X, X, X, X, X, X,
|
||||
3, 6, 11, 3, 0, 6, 0, 4, 6, X, X, X, X, X, X, X,
|
||||
8, 6, 11, 8, 4, 6, 9, 0, 1, X, X, X, X, X, X, X,
|
||||
9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, X, X, X, X,
|
||||
6, 8, 4, 6, 11, 8, 2, 10, 1, X, X, X, X, X, X, X,
|
||||
1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, X, X, X, X,
|
||||
4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, X, X, X, X,
|
||||
10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, X,
|
||||
8, 2, 3, 8, 4, 2, 4, 6, 2, X, X, X, X, X, X, X,
|
||||
0, 4, 2, 4, 6, 2, X, X, X, X, X, X, X, X, X, X,
|
||||
1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, X, X, X, X,
|
||||
1, 9, 4, 1, 4, 2, 2, 4, 6, X, X, X, X, X, X, X,
|
||||
8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, X, X, X, X,
|
||||
10, 1, 0, 10, 0, 6, 6, 0, 4, X, X, X, X, X, X, X,
|
||||
4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, X,
|
||||
10, 9, 4, 6, 10, 4, X, X, X, X, X, X, X, X, X, X,
|
||||
4, 9, 5, 7, 6, 11, X, X, X, X, X, X, X, X, X, X,
|
||||
0, 8, 3, 4, 9, 5, 11, 7, 6, X, X, X, X, X, X, X,
|
||||
5, 0, 1, 5, 4, 0, 7, 6, 11, X, X, X, X, X, X, X,
|
||||
11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, X, X, X, X,
|
||||
9, 5, 4, 10, 1, 2, 7, 6, 11, X, X, X, X, X, X, X,
|
||||
6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, X, X, X, X,
|
||||
7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, X, X, X, X,
|
||||
3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, X,
|
||||
7, 2, 3, 7, 6, 2, 5, 4, 9, X, X, X, X, X, X, X,
|
||||
9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, X, X, X, X,
|
||||
3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, X, X, X, X,
|
||||
6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, X,
|
||||
9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, X, X, X, X,
|
||||
1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, X,
|
||||
4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, X,
|
||||
7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, X, X, X, X,
|
||||
6, 9, 5, 6, 11, 9, 11, 8, 9, X, X, X, X, X, X, X,
|
||||
3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, X, X, X, X,
|
||||
0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, X, X, X, X,
|
||||
6, 11, 3, 6, 3, 5, 5, 3, 1, X, X, X, X, X, X, X,
|
||||
1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, X, X, X, X,
|
||||
0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, X,
|
||||
11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, X,
|
||||
6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, X, X, X, X,
|
||||
5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, X, X, X, X,
|
||||
9, 5, 6, 9, 6, 0, 0, 6, 2, X, X, X, X, X, X, X,
|
||||
1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, X,
|
||||
1, 5, 6, 2, 1, 6, X, X, X, X, X, X, X, X, X, X,
|
||||
1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, X,
|
||||
10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, X, X, X, X,
|
||||
0, 3, 8, 5, 6, 10, X, X, X, X, X, X, X, X, X, X,
|
||||
10, 5, 6, X, X, X, X, X, X, X, X, X, X, X, X, X,
|
||||
11, 5, 10, 7, 5, 11, X, X, X, X, X, X, X, X, X, X,
|
||||
11, 5, 10, 11, 7, 5, 8, 3, 0, X, X, X, X, X, X, X,
|
||||
5, 11, 7, 5, 10, 11, 1, 9, 0, X, X, X, X, X, X, X,
|
||||
10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, X, X, X, X,
|
||||
11, 1, 2, 11, 7, 1, 7, 5, 1, X, X, X, X, X, X, X,
|
||||
0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, X, X, X, X,
|
||||
9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, X, X, X, X,
|
||||
7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, X,
|
||||
2, 5, 10, 2, 3, 5, 3, 7, 5, X, X, X, X, X, X, X,
|
||||
8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, X, X, X, X,
|
||||
9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, X, X, X, X,
|
||||
9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, X,
|
||||
1, 3, 5, 3, 7, 5, X, X, X, X, X, X, X, X, X, X,
|
||||
0, 8, 7, 0, 7, 1, 1, 7, 5, X, X, X, X, X, X, X,
|
||||
9, 0, 3, 9, 3, 5, 5, 3, 7, X, X, X, X, X, X, X,
|
||||
9, 8, 7, 5, 9, 7, X, X, X, X, X, X, X, X, X, X,
|
||||
5, 8, 4, 5, 10, 8, 10, 11, 8, X, X, X, X, X, X, X,
|
||||
5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, X, X, X, X,
|
||||
0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, X, X, X, X,
|
||||
10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, X,
|
||||
2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, X, X, X, X,
|
||||
0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, X,
|
||||
0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, X,
|
||||
9, 4, 5, 2, 11, 3, X, X, X, X, X, X, X, X, X, X,
|
||||
2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, X, X, X, X,
|
||||
5, 10, 2, 5, 2, 4, 4, 2, 0, X, X, X, X, X, X, X,
|
||||
3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, X,
|
||||
5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, X, X, X, X,
|
||||
8, 4, 5, 8, 5, 3, 3, 5, 1, X, X, X, X, X, X, X,
|
||||
0, 4, 5, 1, 0, 5, X, X, X, X, X, X, X, X, X, X,
|
||||
8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, X, X, X, X,
|
||||
9, 4, 5, X, X, X, X, X, X, X, X, X, X, X, X, X,
|
||||
4, 11, 7, 4, 9, 11, 9, 10, 11, X, X, X, X, X, X, X,
|
||||
0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, X, X, X, X,
|
||||
1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, X, X, X, X,
|
||||
3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, X,
|
||||
4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, X, X, X, X,
|
||||
9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, X,
|
||||
11, 7, 4, 11, 4, 2, 2, 4, 0, X, X, X, X, X, X, X,
|
||||
11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, X, X, X, X,
|
||||
2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, X, X, X, X,
|
||||
9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, X,
|
||||
3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, X,
|
||||
1, 10, 2, 8, 7, 4, X, X, X, X, X, X, X, X, X, X,
|
||||
4, 9, 1, 4, 1, 7, 7, 1, 3, X, X, X, X, X, X, X,
|
||||
4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, X, X, X, X,
|
||||
4, 0, 3, 7, 4, 3, X, X, X, X, X, X, X, X, X, X,
|
||||
4, 8, 7, X, X, X, X, X, X, X, X, X, X, X, X, X,
|
||||
9, 10, 8, 10, 11, 8, X, X, X, X, X, X, X, X, X, X,
|
||||
3, 0, 9, 3, 9, 11, 11, 9, 10, X, X, X, X, X, X, X,
|
||||
0, 1, 10, 0, 10, 8, 8, 10, 11, X, X, X, X, X, X, X,
|
||||
3, 1, 10, 11, 3, 10, X, X, X, X, X, X, X, X, X, X,
|
||||
1, 2, 11, 1, 11, 9, 9, 11, 8, X, X, X, X, X, X, X,
|
||||
3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, X, X, X, X,
|
||||
0, 2, 11, 8, 0, 11, X, X, X, X, X, X, X, X, X, X,
|
||||
3, 2, 11, X, X, X, X, X, X, X, X, X, X, X, X, X,
|
||||
2, 3, 8, 2, 8, 10, 10, 8, 9, X, X, X, X, X, X, X,
|
||||
9, 10, 2, 0, 9, 2, X, X, X, X, X, X, X, X, X, X,
|
||||
2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, X, X, X, X,
|
||||
1, 10, 2, X, X, X, X, X, X, X, X, X, X, X, X, X,
|
||||
1, 3, 8, 9, 1, 8, X, X, X, X, X, X, X, X, X, X,
|
||||
0, 9, 1, X, X, X, X, X, X, X, X, X, X, X, X, X,
|
||||
0, 3, 8, X, X, X, X, X, X, X, X, X, X, X, X, X,
|
||||
X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X
|
||||
#undef X
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -22,6 +22,7 @@ set(unit_tests
|
||||
UnitTestCellAverage.cxx
|
||||
UnitTestClipping.cxx
|
||||
UnitTestExternalFaces.cxx
|
||||
UnitTestIsosurfaceUniformGrid.cxx
|
||||
UnitTestPointElevation.cxx
|
||||
UnitTestWorkletMapField.cxx
|
||||
UnitTestWorkletMapFieldExecArg.cxx
|
||||
|
138
vtkm/worklet/testing/UnitTestIsosurfaceUniformGrid.cxx
Normal file
138
vtkm/worklet/testing/UnitTestIsosurfaceUniformGrid.cxx
Normal file
@ -0,0 +1,138 @@
|
||||
//============================================================================
|
||||
// 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.
|
||||
//
|
||||
// Copyright 2014 Sandia Corporation.
|
||||
// Copyright 2014 UT-Battelle, LLC.
|
||||
// Copyright 2014 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
||||
// the U.S. Government retains certain rights in this software.
|
||||
//
|
||||
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
|
||||
// Laboratory (LANL), the U.S. Government retains certain rights in
|
||||
// this software.
|
||||
//============================================================================
|
||||
|
||||
#include <vtkm/worklet/IsosurfaceUniformGrid.h>
|
||||
#include <vtkm/worklet/DispatcherMapField.h>
|
||||
|
||||
#include <vtkm/cont/CellSetExplicit.h>
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
|
||||
#include <vtkm/cont/testing/Testing.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
|
||||
class TangleField : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
typedef void ControlSignature(FieldIn<IdType> vertexId, FieldOut<Scalar> v);
|
||||
typedef void ExecutionSignature(_1, _2);
|
||||
typedef _1 InputDomain;
|
||||
|
||||
const vtkm::Id xdim, ydim, zdim;
|
||||
const float xmin, ymin, zmin, xmax, ymax, zmax;
|
||||
const vtkm::Id cellsPerLayer;
|
||||
|
||||
VTKM_CONT_EXPORT
|
||||
TangleField(const vtkm::Id3 dims, const float mins[3], const float maxs[3]) : xdim(dims[0]), ydim(dims[1]), zdim(dims[2]),
|
||||
xmin(mins[0]), ymin(mins[1]), zmin(mins[2]), xmax(maxs[0]), ymax(maxs[1]), zmax(maxs[2]), cellsPerLayer((xdim) * (ydim)) { };
|
||||
|
||||
VTKM_EXEC_EXPORT
|
||||
void operator()(const vtkm::Id &vertexId, vtkm::Float32 &v) const
|
||||
{
|
||||
const vtkm::Id x = vertexId % (xdim);
|
||||
const vtkm::Id y = (vertexId / (xdim)) % (ydim);
|
||||
const vtkm::Id z = vertexId / cellsPerLayer;
|
||||
|
||||
const float fx = static_cast<float>(x) / static_cast<float>(xdim-1);
|
||||
const float fy = static_cast<float>(y) / static_cast<float>(xdim-1);
|
||||
const float fz = static_cast<float>(z) / static_cast<float>(xdim-1);
|
||||
|
||||
const vtkm::Float32 xx = 3.0f*(xmin+(xmax-xmin)*(fx));
|
||||
const vtkm::Float32 yy = 3.0f*(ymin+(ymax-ymin)*(fy));
|
||||
const vtkm::Float32 zz = 3.0f*(zmin+(zmax-zmin)*(fz));
|
||||
|
||||
v = (xx*xx*xx*xx - 5.0f*xx*xx + yy*yy*yy*yy - 5.0f*yy*yy + zz*zz*zz*zz - 5.0f*zz*zz + 11.8f) * 0.2f + 0.5f;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
vtkm::cont::DataSet MakeIsosurfaceTestDataSet(vtkm::Id3 dims)
|
||||
{
|
||||
vtkm::cont::DataSet dataSet;
|
||||
|
||||
const vtkm::Id3 vdims(dims[0] + 1, dims[1] + 1, dims[2] + 1);
|
||||
const vtkm::Id dim3 = dims[0]*dims[1]*dims[2];
|
||||
|
||||
float mins[3] = {-1.0f, -1.0f, -1.0f};
|
||||
float maxs[3] = {1.0f, 1.0f, 1.0f};
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32> fieldArray;
|
||||
vtkm::cont::ArrayHandleCounting<vtkm::Id> vertexCountImplicitArray(0, vdims[0]*vdims[1]*vdims[2]);
|
||||
vtkm::worklet::DispatcherMapField<TangleField> tangleFieldDispatcher(TangleField(vdims, mins, maxs));
|
||||
tangleFieldDispatcher.Invoke(vertexCountImplicitArray, fieldArray);
|
||||
|
||||
vtkm::cont::ArrayHandleUniformPointCoordinates coordinates(vdims);
|
||||
dataSet.AddCoordinateSystem(
|
||||
vtkm::cont::CoordinateSystem("coordinates", 1, coordinates));
|
||||
|
||||
dataSet.AddField(vtkm::cont::Field("nodevar", 1, vtkm::cont::Field::ASSOC_POINTS, fieldArray));
|
||||
|
||||
std::vector<vtkm::Float32> cellvar( static_cast<std::size_t>(dim3) );
|
||||
for(std::size_t i=0; i < cellvar.size(); i++)
|
||||
{
|
||||
cellvar[i] = vtkm::Float32(i);
|
||||
}
|
||||
|
||||
vtkm::cont::Field cellField("cellvar", 1,
|
||||
vtkm::cont::Field::ASSOC_CELL_SET,
|
||||
"cells",
|
||||
cellvar);
|
||||
dataSet.AddField(cellField);
|
||||
|
||||
static const vtkm::IdComponent ndim = 3;
|
||||
vtkm::cont::CellSetStructured<ndim> cellSet("cells");
|
||||
cellSet.SetPointDimensions(vdims);
|
||||
dataSet.AddCellSet(cellSet);
|
||||
|
||||
return dataSet;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void TestIsosurfaceUniformGrid()
|
||||
{
|
||||
std::cout << "Testing IsosurfaceUniformGrid Filter" << std::endl;
|
||||
|
||||
vtkm::Id3 dims(4,4,4);
|
||||
vtkm::cont::DataSet dataSet = MakeIsosurfaceTestDataSet(dims);
|
||||
|
||||
typedef VTKM_DEFAULT_DEVICE_ADAPTER_TAG DeviceAdapter;
|
||||
|
||||
vtkm::worklet::IsosurfaceFilterUniformGrid<vtkm::Float32,
|
||||
DeviceAdapter> isosurfaceFilter(dims, dataSet);
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32,3> > verticesArray;
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32> scalarsArray;
|
||||
isosurfaceFilter.Run(0.5,
|
||||
dataSet.GetField("nodevar").GetData(),
|
||||
verticesArray,
|
||||
scalarsArray);
|
||||
|
||||
VTKM_TEST_ASSERT(test_equal(verticesArray.GetNumberOfValues(), 480),
|
||||
"Wrong result for Isosurface filter");
|
||||
}
|
||||
|
||||
int UnitTestIsosurfaceUniformGrid(int, char *[])
|
||||
{
|
||||
return vtkm::cont::testing::Testing::Run(TestIsosurfaceUniformGrid);
|
||||
}
|
Loading…
Reference in New Issue
Block a user