mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-08 13:23:51 +00:00
Merge topic 'marching_cubes_faster_structured_normals'
1147edb1 MarchingCubes now uses Gradient fast paths when possible. d7d5da4f More changes to Neighborhood code to make it more easy to use. Acked-by: Kitware Robot <kwrobot@kitware.com> Acked-by: Sujin Philip <sujin.philip@kitware.com> Merge-request: !916
This commit is contained in:
commit
fe028d828a
@ -62,6 +62,12 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
ConnectivityStructured(const ConnectivityStructured<ToTopology, FromTopology, Dimension>& src)
|
||||
: Internals(src.Internals)
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_EXEC
|
||||
vtkm::Id GetNumberOfElements() const { return Helper::GetNumberOfElements(this->Internals); }
|
||||
|
||||
@ -113,6 +119,8 @@ public:
|
||||
return this->Internals.GetPointDimensions();
|
||||
}
|
||||
|
||||
friend class ConnectivityStructured<ToTopology, FromTopology, Dimension>;
|
||||
|
||||
private:
|
||||
InternalsType Internals;
|
||||
};
|
||||
|
@ -46,7 +46,7 @@ template <int NeighborhoodSize, typename ExecObjectType>
|
||||
struct Neighborhood
|
||||
{
|
||||
VTKM_EXEC
|
||||
Neighborhood(ExecObjectType portal, const vtkm::exec::arg::BoundaryState& boundary)
|
||||
Neighborhood(const ExecObjectType& portal, const vtkm::exec::arg::BoundaryState& boundary)
|
||||
: Boundary(&boundary)
|
||||
, Portal(portal)
|
||||
{
|
||||
@ -83,7 +83,7 @@ template <int NeighborhoodSize>
|
||||
struct Neighborhood<NeighborhoodSize, vtkm::internal::ArrayPortalUniformPointCoordinates>
|
||||
{
|
||||
VTKM_EXEC
|
||||
Neighborhood(vtkm::internal::ArrayPortalUniformPointCoordinates portal,
|
||||
Neighborhood(const vtkm::internal::ArrayPortalUniformPointCoordinates& portal,
|
||||
const vtkm::exec::arg::BoundaryState& boundary)
|
||||
: Boundary(&boundary)
|
||||
, Portal(portal)
|
||||
|
@ -266,7 +266,26 @@ public:
|
||||
NeighborhoodSize)
|
||||
, InputIndex(outToIn.Get(outIndex))
|
||||
, OutputIndex(outIndex)
|
||||
, VisitIndex(static_cast<vtkm::IdComponent>(visit.Get(this->OutputIndex)))
|
||||
, VisitIndex(static_cast<vtkm::IdComponent>(visit.Get(outIndex)))
|
||||
, GlobalThreadIndexOffset(globalThreadIndexOffset)
|
||||
{
|
||||
}
|
||||
|
||||
template <vtkm::IdComponent Dimension>
|
||||
VTKM_EXEC ThreadIndicesPointNeighborhood(
|
||||
const vtkm::Id& outIndex,
|
||||
const vtkm::Id& inIndex,
|
||||
const vtkm::IdComponent& visitIndex,
|
||||
const vtkm::exec::ConnectivityStructured<vtkm::TopologyElementTagCell,
|
||||
vtkm::TopologyElementTagPoint,
|
||||
Dimension>& connectivity,
|
||||
vtkm::Id globalThreadIndexOffset = 0)
|
||||
: State(detail::To3D(connectivity.FlatToLogicalToIndex(inIndex)),
|
||||
detail::To3D(connectivity.GetPointDimensions()),
|
||||
NeighborhoodSize)
|
||||
, InputIndex(inIndex)
|
||||
, OutputIndex(outIndex)
|
||||
, VisitIndex(visitIndex)
|
||||
, GlobalThreadIndexOffset(globalThreadIndexOffset)
|
||||
{
|
||||
}
|
||||
|
@ -429,7 +429,8 @@ void TestNormals(const vtkm::cont::DataSet& dataset, bool structured)
|
||||
{
|
||||
const vtkm::Id numVerts = 16;
|
||||
|
||||
const vtkm::Vec<vtkm::FloatDefault, 3> hq[numVerts] = {
|
||||
//Calculated using PointGradient
|
||||
const vtkm::Vec<vtkm::FloatDefault, 3> hq_ug[numVerts] = {
|
||||
{ 0.1510f, 0.6268f, 0.7644f }, { 0.1333f, -0.3974f, 0.9079f },
|
||||
{ 0.1626f, 0.7642f, 0.6242f }, { 0.3853f, 0.6643f, 0.6405f },
|
||||
{ -0.1337f, 0.7136f, 0.6876f }, { 0.7705f, -0.4212f, 0.4784f },
|
||||
@ -440,6 +441,19 @@ void TestNormals(const vtkm::cont::DataSet& dataset, bool structured)
|
||||
{ 0.1234f, -0.8871f, -0.4448f }, { 0.1333f, -0.3974f, -0.9079f }
|
||||
};
|
||||
|
||||
//Calculated using StructuredPointGradient
|
||||
const vtkm::Vec<vtkm::FloatDefault, 3> hq_sg[numVerts] = {
|
||||
{ 0.165519f, 0.687006f, 0.707549f }, { 0.188441f, -0.561729f, 0.805574f },
|
||||
{ 0.179543f, 0.702158f, 0.689012f }, { 0.271085f, 0.692957f, 0.668074f },
|
||||
{ 0.00313049f, 0.720109f, 0.693854f }, { 0.549947f, -0.551974f, 0.626804f },
|
||||
{ -0.447526f, -0.588187f, 0.673614f }, { 0.167553f, -0.779396f, 0.603711f },
|
||||
{ 0.179543f, 0.702158f, -0.689012f }, { 0.271085f, 0.692957f, -0.668074f },
|
||||
{ 0.00313049f, 0.720109f, -0.693854f }, { 0.165519f, 0.687006f, -0.707549f },
|
||||
{ 0.549947f, -0.551974f, -0.626804f }, { -0.447526f, -0.588187f, -0.673614f },
|
||||
{ 0.167553f, -0.779396f, -0.603711f }, { 0.188441f, -0.561729f, -0.805574f }
|
||||
};
|
||||
|
||||
//Calculated using normals of the output triangles
|
||||
const vtkm::Vec<vtkm::FloatDefault, 3> fast[numVerts] = {
|
||||
{ -0.1351f, 0.4377f, 0.8889f }, { 0.2863f, -0.1721f, 0.9426f },
|
||||
{ 0.3629f, 0.8155f, 0.4509f }, { 0.8486f, 0.3560f, 0.3914f },
|
||||
@ -458,7 +472,7 @@ void TestNormals(const vtkm::cont::DataSet& dataset, bool structured)
|
||||
mc.SetGenerateNormals(true);
|
||||
|
||||
// Test default normals generation: high quality for structured, fast for unstructured.
|
||||
auto expected = structured ? hq : fast;
|
||||
auto expected = structured ? hq_sg : fast;
|
||||
|
||||
auto result = mc.Execute(dataset, dataset.GetField("pointvar"));
|
||||
result.GetDataSet().GetField("normals").GetData().CopyTo(normals);
|
||||
@ -479,7 +493,7 @@ void TestNormals(const vtkm::cont::DataSet& dataset, bool structured)
|
||||
else
|
||||
{
|
||||
mc.SetComputeFastNormalsForUnstructured(false);
|
||||
expected = hq;
|
||||
expected = hq_ug;
|
||||
}
|
||||
|
||||
result = mc.Execute(dataset, dataset.GetField("pointvar"));
|
||||
|
@ -43,7 +43,6 @@ set(headers
|
||||
Keys.h
|
||||
Magnitude.h
|
||||
MarchingCubes.h
|
||||
MarchingCubesDataTables.h
|
||||
Mask.h
|
||||
MaskPoints.h
|
||||
NDimsEntropy.h
|
||||
@ -74,6 +73,7 @@ set(headers
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
add_subdirectory(internal)
|
||||
add_subdirectory(contour)
|
||||
add_subdirectory(contourtree)
|
||||
add_subdirectory(cosmotools)
|
||||
add_subdirectory(gradient)
|
||||
|
@ -41,15 +41,18 @@
|
||||
#include <vtkm/cont/Field.h>
|
||||
|
||||
#include <vtkm/worklet/DispatcherMapTopology.h>
|
||||
#include <vtkm/worklet/DispatcherPointNeighborhood.h>
|
||||
#include <vtkm/worklet/DispatcherReduceByKey.h>
|
||||
#include <vtkm/worklet/Keys.h>
|
||||
#include <vtkm/worklet/ScatterCounting.h>
|
||||
#include <vtkm/worklet/ScatterPermutation.h>
|
||||
#include <vtkm/worklet/WorkletMapTopology.h>
|
||||
#include <vtkm/worklet/WorkletPointNeighborhood.h>
|
||||
#include <vtkm/worklet/WorkletReduceByKey.h>
|
||||
#include <vtkm/worklet/gradient/PointGradient.h>
|
||||
|
||||
#include <vtkm/worklet/MarchingCubesDataTables.h>
|
||||
#include <vtkm/worklet/contour/DataTables.h>
|
||||
#include <vtkm/worklet/gradient/PointGradient.h>
|
||||
#include <vtkm/worklet/gradient/StructuredPointGradient.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
@ -526,10 +529,40 @@ public:
|
||||
const WholeFieldIn& inputField,
|
||||
NormalType& normal) const
|
||||
{
|
||||
vtkm::worklet::gradient::PointGradient<WholeFieldIn> gradient;
|
||||
using T = typename WholeFieldIn::ValueType;
|
||||
vtkm::worklet::gradient::PointGradient<T> gradient;
|
||||
gradient(numCells, cellIds, pointId, geometry, pointCoordinates, inputField, normal);
|
||||
}
|
||||
|
||||
template <typename FromIndexType,
|
||||
typename WholeCoordinatesIn,
|
||||
typename WholeFieldIn,
|
||||
typename NormalType>
|
||||
VTKM_EXEC void operator()(const vtkm::IdComponent& vtkmNotUsed(numCells),
|
||||
const FromIndexType& vtkmNotUsed(cellIds),
|
||||
vtkm::Id pointId,
|
||||
vtkm::exec::ConnectivityStructured<Point, Cell, 3>& geometry,
|
||||
const WholeCoordinatesIn& pointCoordinates,
|
||||
const WholeFieldIn& inputField,
|
||||
NormalType& normal) const
|
||||
{
|
||||
using T = typename WholeFieldIn::ValueType;
|
||||
|
||||
//Optimization for structured cellsets so we can call StructuredPointGradient
|
||||
//and have way faster gradients
|
||||
vtkm::exec::ConnectivityStructured<Cell, Point, 3> pointGeom(geometry);
|
||||
vtkm::exec::arg::ThreadIndicesPointNeighborhood<3> tpn(pointId, pointId, 0, pointGeom, 0);
|
||||
|
||||
const auto& boundary = tpn.GetBoundaryState();
|
||||
auto pointPortal = pointCoordinates.GetPortal();
|
||||
auto fieldPortal = inputField.GetPortal();
|
||||
vtkm::exec::arg::Neighborhood<1, decltype(pointPortal)> points(pointPortal, boundary);
|
||||
vtkm::exec::arg::Neighborhood<1, decltype(fieldPortal)> field(fieldPortal, boundary);
|
||||
|
||||
vtkm::worklet::gradient::StructuredPointGradient<T> gradient;
|
||||
gradient(boundary, points, field, normal);
|
||||
}
|
||||
|
||||
ScatterType GetScatter() const { return this->Scatter; }
|
||||
|
||||
private:
|
||||
@ -577,7 +610,8 @@ public:
|
||||
const WholeWeightsIn& weights,
|
||||
NormalType& normal) const
|
||||
{
|
||||
vtkm::worklet::gradient::PointGradient<NormalType> gradient;
|
||||
using T = typename WholeFieldIn::ValueType;
|
||||
vtkm::worklet::gradient::PointGradient<T> gradient;
|
||||
NormalType grad1;
|
||||
gradient(numCells, cellIds, pointId, geometry, pointCoordinates, inputField, grad1);
|
||||
|
||||
@ -586,6 +620,42 @@ public:
|
||||
normal = vtkm::Normal(vtkm::Lerp(grad0, grad1, weight));
|
||||
}
|
||||
|
||||
template <typename FromIndexType,
|
||||
typename WholeCoordinatesIn,
|
||||
typename WholeFieldIn,
|
||||
typename WholeWeightsIn,
|
||||
typename NormalType>
|
||||
VTKM_EXEC void operator()(const vtkm::IdComponent& vtkmNotUsed(numCells),
|
||||
const FromIndexType& vtkmNotUsed(cellIds),
|
||||
vtkm::Id pointId,
|
||||
vtkm::exec::ConnectivityStructured<Point, Cell, 3>& geometry,
|
||||
const WholeCoordinatesIn& pointCoordinates,
|
||||
const WholeFieldIn& inputField,
|
||||
vtkm::Id edgeId,
|
||||
const WholeWeightsIn& weights,
|
||||
NormalType& normal) const
|
||||
{
|
||||
using T = typename WholeFieldIn::ValueType;
|
||||
//Optimization for structured cellsets so we can call StructuredPointGradient
|
||||
//and have way faster gradients
|
||||
vtkm::exec::ConnectivityStructured<Cell, Point, 3> pointGeom(geometry);
|
||||
vtkm::exec::arg::ThreadIndicesPointNeighborhood<3> tpn(pointId, pointId, 0, pointGeom, 0);
|
||||
|
||||
const auto& boundary = tpn.GetBoundaryState();
|
||||
auto pointPortal = pointCoordinates.GetPortal();
|
||||
auto fieldPortal = inputField.GetPortal();
|
||||
vtkm::exec::arg::Neighborhood<1, decltype(pointPortal)> points(pointPortal, boundary);
|
||||
vtkm::exec::arg::Neighborhood<1, decltype(fieldPortal)> field(fieldPortal, boundary);
|
||||
|
||||
vtkm::worklet::gradient::StructuredPointGradient<T> gradient;
|
||||
NormalType grad1;
|
||||
gradient(boundary, points, field, grad1);
|
||||
|
||||
NormalType grad0 = normal;
|
||||
auto weight = weights.Get(edgeId);
|
||||
normal = vtkm::Normal(vtkm::Lerp(grad0, grad1, weight));
|
||||
}
|
||||
|
||||
ScatterType GetScatter() const { return this->Scatter; }
|
||||
|
||||
private:
|
||||
|
26
vtkm/worklet/contour/CMakeLists.txt
Normal file
26
vtkm/worklet/contour/CMakeLists.txt
Normal file
@ -0,0 +1,26 @@
|
||||
##============================================================================
|
||||
## 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 2016 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
## Copyright 2016 UT-Battelle, LLC.
|
||||
## Copyright 2016 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.
|
||||
##============================================================================
|
||||
|
||||
set(headers
|
||||
DataTables.h
|
||||
)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
vtkm_declare_headers(${headers})
|
@ -58,6 +58,7 @@ struct StructuredPointGradient : public vtkm::worklet::WorkletPointNeighborhood3
|
||||
{
|
||||
using CoordType = typename PointsIn::ValueType;
|
||||
using CT = typename vtkm::BaseComponent<CoordType>::Type;
|
||||
using OT = typename GradientOutType::ComponentType;
|
||||
|
||||
vtkm::Vec<CT, 3> xi, eta, zeta;
|
||||
this->Jacobian(inputPoints, boundary, xi, eta, zeta); //store the metrics in xi,eta,zeta
|
||||
@ -70,9 +71,9 @@ struct StructuredPointGradient : public vtkm::worklet::WorkletPointNeighborhood3
|
||||
deta = (boundary.OnY() ? deta : deta * 0.5f);
|
||||
dzeta = (boundary.OnZ() ? dzeta : dzeta * 0.5f);
|
||||
|
||||
outputGradient[0] = static_cast<T>(xi[0] * dxi + eta[0] * deta + zeta[0] * dzeta);
|
||||
outputGradient[1] = static_cast<T>(xi[1] * dxi + eta[1] * deta + zeta[1] * dzeta);
|
||||
outputGradient[2] = static_cast<T>(xi[2] * dxi + eta[2] * deta + zeta[2] * dzeta);
|
||||
outputGradient[0] = static_cast<OT>(xi[0] * dxi + eta[0] * deta + zeta[0] * dzeta);
|
||||
outputGradient[1] = static_cast<OT>(xi[1] * dxi + eta[1] * deta + zeta[1] * dzeta);
|
||||
outputGradient[2] = static_cast<OT>(xi[2] * dxi + eta[2] * deta + zeta[2] * dzeta);
|
||||
}
|
||||
|
||||
template <typename FieldIn, typename GradientOutType>
|
||||
@ -89,6 +90,8 @@ struct StructuredPointGradient : public vtkm::worklet::WorkletPointNeighborhood3
|
||||
using PointsIn =
|
||||
vtkm::exec::arg::Neighborhood<1, vtkm::internal::ArrayPortalUniformPointCoordinates>;
|
||||
using CoordType = typename PointsIn::ValueType;
|
||||
using OT = typename GradientOutType::ComponentType;
|
||||
|
||||
|
||||
CoordType r = inputPoints.Portal.GetSpacing();
|
||||
|
||||
@ -100,9 +103,9 @@ struct StructuredPointGradient : public vtkm::worklet::WorkletPointNeighborhood3
|
||||
const T dy = inputField.Get(0, 1, 0) - inputField.Get(0, -1, 0);
|
||||
const T dz = inputField.Get(0, 0, 1) - inputField.Get(0, 0, -1);
|
||||
|
||||
outputGradient[0] = dx * r[0];
|
||||
outputGradient[1] = dy * r[1];
|
||||
outputGradient[2] = dz * r[2];
|
||||
outputGradient[0] = static_cast<OT>(dx * r[0]);
|
||||
outputGradient[1] = static_cast<OT>(dy * r[1]);
|
||||
outputGradient[2] = static_cast<OT>(dz * r[2]);
|
||||
}
|
||||
|
||||
//we need to pass the coordinates into this function, and instead
|
||||
|
Loading…
Reference in New Issue
Block a user