//============================================================================ // 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 #include #include #include #include #include #include #include static bool printProgress = true; template VTKM_EXEC_CONT vtkm::Vec Normalize(vtkm::Vec v) { T magnitude = static_cast(sqrt(vtkm::dot(v, v))); T zero = static_cast(0.0); T one = static_cast(1.0); if (magnitude == zero) return vtkm::make_Vec(zero, zero, zero); else return one / magnitude * v; } class TangleField : public vtkm::worklet::WorkletMapField { public: using ControlSignature = void(FieldIn vertexId, FieldOut v); using ExecutionSignature = void(_1, _2); using InputDomain = _1; const vtkm::Id xdim, ydim, zdim; const vtkm::FloatDefault xmin, ymin, zmin, xmax, ymax, zmax; const vtkm::Id cellsPerLayer; VTKM_CONT TangleField(const vtkm::Id3 dims, const vtkm::FloatDefault mins[3], const vtkm::FloatDefault 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 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 vtkm::FloatDefault fx = static_cast(x) / static_cast(xdim - 1); const vtkm::FloatDefault fy = static_cast(y) / static_cast(xdim - 1); const vtkm::FloatDefault fz = static_cast(z) / static_cast(xdim - 1); const vtkm::Float32 xx = 3.0f * vtkm::Float32(xmin + (xmax - xmin) * (fx)); const vtkm::Float32 yy = 3.0f * vtkm::Float32(ymin + (ymax - ymin) * (fy)); const vtkm::Float32 zz = 3.0f * vtkm::Float32(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 CreateTestDataSet(vtkm::Id3 dims) { vtkm::cont::DataSet dataSet; const vtkm::Id3 vdims(dims[0] + 1, dims[1] + 1, dims[2] + 1); vtkm::FloatDefault mins[3] = { -1.0f, -1.0f, -1.0f }; vtkm::FloatDefault maxs[3] = { 1.0f, 1.0f, 1.0f }; static const vtkm::IdComponent ndim = 3; vtkm::cont::CellSetStructured cellSet("cells"); cellSet.SetPointDimensions(vdims); dataSet.AddCellSet(cellSet); vtkm::Vec3f origin(0.0f, 0.0f, 0.0f); vtkm::Vec3f spacing(1.0f / static_cast(dims[0]), 1.0f / static_cast(dims[2]), 1.0f / static_cast(dims[1])); vtkm::cont::ArrayHandleUniformPointCoordinates coordinates(vdims, origin, spacing); dataSet.AddCoordinateSystem(vtkm::cont::CoordinateSystem("coordinates", coordinates)); vtkm::cont::ArrayHandle scalarVar; vtkm::cont::ArrayHandleIndex vertexCountImplicitArray(vdims[0] * vdims[1] * vdims[2]); vtkm::worklet::DispatcherMapField tangleFieldDispatcher( TangleField(vdims, mins, maxs)); tangleFieldDispatcher.Invoke(vertexCountImplicitArray, scalarVar); dataSet.AddField( vtkm::cont::Field(std::string("scalar"), vtkm::cont::Field::Association::POINTS, scalarVar)); return dataSet; } void TestMarchingCubesUniformGrid(int d) { vtkm::Id3 dims(d, d, d); std::cout << "Marching cubes with gridsize = " << dims << std::endl; vtkm::cont::DataSet dataSet = CreateTestDataSet(dims); //vtkm::io::writer::VTKDataSetWriter wrt("ds.vtk"); //wrt.WriteDataSet(dataSet); int N = 100; vtkm::Float32 v0 = -.8f, v1 = 24.0f; vtkm::Float32 dv = (v1 - v0) / (vtkm::Float32)(N - 1); for (int i = 0; i < N; i++) { vtkm::filter::ResultDataSet result; vtkm::filter::MarchingCubes mc; mc.SetGenerateNormals(true); vtkm::Float32 val = v0 + i * dv; //std::cout<* streamLineFilter; streamLineFilter = new vtkm::worklet::StreamLineFilterUniformGrid(); std::cout << "Streamline test: " << N << std::endl; for (int i = 0; i < N; i++) { if (printProgress && i % 10 == 0) std::cout << " " << i << " of " << N << std::endl; vtkm::cont::DataSet out; out = streamLineFilter->Run(ds, direction, nSeeds, nSteps, tStep); } } void RenderRTTest(const vtkm::cont::DataSet& ds, int N) { std::cout << "Ray Tracing test: " << N << std::endl; for (int i = 0; i < N; i++) { if (printProgress && i % 10 == 0) std::cout << " " << i << " of " << N << std::endl; using M = vtkm::rendering::MapperRayTracer; using C = vtkm::rendering::CanvasRayTracer; using V3 = vtkm::rendering::View3D; //std::cout<<"Render: "<(ds, "scalar", colorTable); } } void RenderVolTest(const vtkm::cont::DataSet& ds, int N) { std::cout << "Volume Rendering test :" << N << std::endl; for (int i = 0; i < N; i++) { if (printProgress && i % 10 == 0) std::cout << " " << i << " of " << N << std::endl; using M = vtkm::rendering::MapperVolume; using C = vtkm::rendering::CanvasRayTracer; using V3 = vtkm::rendering::View3D; //std::cout<<"Render: "<(ds, "scalar", colorTable); } } void ExternalFacesTest(const vtkm::cont::DataSet& ds, int N) { std::cout << "External Face test: " << N << std::endl; for (int i = 0; i < N; i++) { if (printProgress && i % 10 == 0) std::cout << " " << i << " of " << N << std::endl; vtkm::cont::CellSetExplicit<> inCellSet; //vtkm::cont::CellSetSingleType<> inCellSet; ds.GetCellSet(0).CopyTo(inCellSet); vtkm::cont::CellSetExplicit<> outCellSet("cells"); //vtkm::cont::CellSetSingleType<> outCellSet("cells"); //Run the External Faces worklet vtkm::worklet::ExternalFaces().Run(inCellSet, outCellSet, VTKM_DEFAULT_DEVICE_ADAPTER_TAG()); vtkm::cont::DataSet outDataSet; for (vtkm::IdComponent i = 0; i < ds.GetNumberOfCoordinateSystems(); ++i) outDataSet.AddCoordinateSystem(ds.GetCoordinateSystem(i)); outDataSet.AddCellSet(outCellSet); } } /* Notes: render: 256 reg and rect. 100 iterations. expl: external faces requires non-SingleType explicit. Forced reader to use this. streamlines: vector field must be named "vecData" */ int main(int argc, char** argv) { // Process vtk-m general args auto opts = vtkm::cont::InitializeOptions::DefaultAnyDevice; auto config = vtkm::cont::Initialize(argc, argv, opts); if (argc != 5) { std::cout << "Error: " << argv[0] << " [options] N SZ " << std::endl; std::cout << "General Options: \n" << config.Usage << std::endl; return -1; } std::string alg = argv[1]; int N = atoi(argv[2]); if (alg == "sl") { char fname[64]; sprintf(fname, "../data/tornado.vec"); std::cout << "Reading file: " << fname << std::endl; FILE* pFile = fopen(fname, "rb"); int dims[3]; size_t ret_code = fread(dims, sizeof(int), 3, pFile); const vtkm::Id3 vdims(dims[0], dims[1], dims[2]); vtkm::Id nElements = vdims[0] * vdims[1] * vdims[2] * 3; float* data = new float[static_cast(nElements)]; ret_code = fread(data, sizeof(float), static_cast(nElements), pFile); fclose(pFile); std::vector field; for (vtkm::Id i = 0; i < nElements; i++) { vtkm::Float32 x = data[i]; vtkm::Float32 y = data[++i]; vtkm::Float32 z = data[++i]; vtkm::Vec3f_32 vecData(x, y, z); field.push_back(Normalize(vecData)); } vtkm::cont::ArrayHandle fieldArray; fieldArray = vtkm::cont::make_ArrayHandle(field); // Construct the input dataset (uniform) to hold the input and set vector data vtkm::cont::DataSet ds; vtkm::cont::ArrayHandleUniformPointCoordinates coordinates(vdims); ds.AddCoordinateSystem(vtkm::cont::CoordinateSystem("coordinates", coordinates)); ds.AddField(vtkm::cont::Field("vec", vtkm::cont::Field::Association::POINTS, fieldArray)); vtkm::cont::CellSetStructured<3> inCellSet("cells"); inCellSet.SetPointDimensions(vtkm::make_Vec(vdims[0], vdims[1], vdims[2])); ds.AddCellSet(inCellSet); StreamlineTest(ds, N); return 0; } else { int sz = atoi(argv[3]); std::string ftype = argv[4]; char fname[64]; sprintf(fname, "../data/s%s_%d.vtk", ftype.c_str(), sz); std::cout << "FNAME= " << fname << std::endl; vtkm::cont::DataSet ds; if (sz < 0) { vtkm::cont::testing::MakeTestDataSet dataSetMaker; ds = dataSetMaker.Make3DExplicitDataSet5(); } else { std::cout << "Reading file: " << fname << std::endl; vtkm::io::reader::VTKDataSetReader rdr(fname); ds = rdr.ReadDataSet(); } if (alg == "iso") MarchingCubesTest(ds, N); else if (alg == "ext") ExternalFacesTest(ds, N); else if (alg == "rt") RenderRTTest(ds, N); else if (alg == "vol") RenderVolTest(ds, N); return 0; } }