//============================================================================ // 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 National Technology & Engineering Solutions of Sandia, LLC (NTESS). // Copyright 2015 UT-Battelle, LLC. // Copyright 2015 Los Alamos National Security. // // Under the terms of Contract DE-NA0003525 with NTESS, // 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_TetrahedralizeExplicit_h #define vtk_m_worklet_TetrahedralizeExplicit_h #include #include #include #include #include #include #include #include #include #include #include #include #include namespace vtkm { namespace worklet { /// \brief Compute the tetrahedralize cells for an explicit grid data set template class TetrahedralizeExplicit { public: TetrahedralizeExplicit() {} // // Worklet to count the number of tetrahedra generated per cell // class TetrahedraPerCell : public vtkm::worklet::WorkletMapField { public: using ControlSignature = void(FieldIn<> shapes, ExecObject tables, FieldOut<> tetrahedronCount); using ExecutionSignature = _3(_1, _2); using InputDomain = _1; VTKM_CONT TetrahedraPerCell() {} VTKM_EXEC vtkm::IdComponent operator()( vtkm::UInt8 shape, const vtkm::worklet::internal::TetrahedralizeTablesExecutionObject& tables) const { return tables.GetCount(vtkm::CellShapeTagGeneric(shape)); } }; // // Worklet to turn cells into tetrahedra // Vertices remain the same and each cell is processed with needing topology // class TetrahedralizeCell : public vtkm::worklet::WorkletMapPointToCell { public: using ControlSignature = void(CellSetIn cellset, ExecObject tables, FieldOutCell<> connectivityOut); using ExecutionSignature = void(CellShape, PointIndices, _2, _3, VisitIndex); using InputDomain = _1; using ScatterType = vtkm::worklet::ScatterCounting; template VTKM_CONT static ScatterType MakeScatter(const CellArrayType& cellArray) { return ScatterType(cellArray, DeviceAdapter()); } // Each cell produces tetrahedra and write result at the offset template VTKM_EXEC void operator()( CellShapeTag shape, const ConnectivityInVec& connectivityIn, const vtkm::worklet::internal::TetrahedralizeTablesExecutionObject& tables, ConnectivityOutVec& connectivityOut, vtkm::IdComponent visitIndex) const { vtkm::Vec tetIndices = tables.GetIndices(shape, visitIndex); connectivityOut[0] = connectivityIn[tetIndices[0]]; connectivityOut[1] = connectivityIn[tetIndices[1]]; connectivityOut[2] = connectivityIn[tetIndices[2]]; connectivityOut[3] = connectivityIn[tetIndices[3]]; } }; template vtkm::cont::CellSetSingleType<> Run(const CellSetType& cellSet, vtkm::cont::ArrayHandle& outCellsPerCell) { vtkm::cont::CellSetSingleType<> outCellSet(cellSet.GetName()); // Input topology auto inShapes = cellSet.GetShapesArray(vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell()); auto inNumIndices = cellSet.GetNumIndicesArray(vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell()); // Output topology vtkm::cont::ArrayHandle outConnectivity; vtkm::worklet::internal::TetrahedralizeTables tables; // Determine the number of output cells each input cell will generate vtkm::worklet::DispatcherMapField tetPerCellDispatcher; tetPerCellDispatcher.Invoke(inShapes, tables.PrepareForInput(), outCellsPerCell); // Build new cells vtkm::worklet::DispatcherMapTopology tetrahedralizeDispatcher(TetrahedralizeCell::MakeScatter(outCellsPerCell)); tetrahedralizeDispatcher.Invoke( cellSet, tables.PrepareForInput(), vtkm::cont::make_ArrayHandleGroupVec<4>(outConnectivity)); // Add cells to output cellset outCellSet.Fill(cellSet.GetNumberOfPoints(), vtkm::CellShapeTagTetra::Id, 4, outConnectivity); return outCellSet; } }; } } // namespace vtkm::worklet #endif // vtk_m_worklet_TetrahedralizeExplicit_h