mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-16 17:22:55 +00:00
Compare commits
2 Commits
5bda11d2fa
...
477c8b488f
Author | SHA1 | Date | |
---|---|---|---|
|
477c8b488f | ||
|
67b200c1d5 |
@ -186,30 +186,30 @@ VTKM_CONT vtkm::cont::PartitionedDataSet SelectTopVolumeContoursFilter::DoExecut
|
||||
branch_top_volume_master.foreach ([&](SelectTopVolumeContoursBlock* b,
|
||||
const vtkmdiy::Master::ProxyWithLink&) {
|
||||
vtkm::cont::Field BranchVolumeField(
|
||||
"BranchVolume", vtkm::cont::Field::Association::WholeDataSet, b->BranchVolume);
|
||||
"BranchVolume", vtkm::cont::Field::Association::WholeDataSet, b->tData.BranchVolume);
|
||||
outputDataSets[b->LocalBlockNo].AddField(BranchVolumeField);
|
||||
vtkm::cont::Field BranchSaddleEpsilonField(
|
||||
"BranchSaddleEpsilon", vtkm::cont::Field::Association::WholeDataSet, b->BranchSaddleEpsilon);
|
||||
"BranchSaddleEpsilon", vtkm::cont::Field::Association::WholeDataSet, b->tData.BranchSaddleEpsilon);
|
||||
outputDataSets[b->LocalBlockNo].AddField(BranchSaddleEpsilonField);
|
||||
vtkm::cont::Field TopVolBranchUpperEndField("TopVolumeBranchUpperEnd",
|
||||
vtkm::cont::Field::Association::WholeDataSet,
|
||||
b->TopVolumeBranchUpperEndGRId);
|
||||
b->tData.TopVolumeBranchUpperEndGRId);
|
||||
outputDataSets[b->LocalBlockNo].AddField(TopVolBranchUpperEndField);
|
||||
vtkm::cont::Field TopVolBranchLowerEndField("TopVolumeBranchLowerEnd",
|
||||
vtkm::cont::Field::Association::WholeDataSet,
|
||||
b->TopVolumeBranchLowerEndGRId);
|
||||
b->tData.TopVolumeBranchLowerEndGRId);
|
||||
outputDataSets[b->LocalBlockNo].AddField(TopVolBranchLowerEndField);
|
||||
vtkm::cont::Field TopVolumeBranchGRIdsField("TopVolumeBranchGlobalRegularIds",
|
||||
vtkm::cont::Field::Association::WholeDataSet,
|
||||
b->TopVolumeBranchRootGRId);
|
||||
b->tData.TopVolumeBranchRootGRId);
|
||||
outputDataSets[b->LocalBlockNo].AddField(TopVolumeBranchGRIdsField);
|
||||
vtkm::cont::Field TopVolBranchVolumeField("TopVolumeBranchVolume",
|
||||
vtkm::cont::Field::Association::WholeDataSet,
|
||||
b->TopVolumeBranchVolume);
|
||||
b->tData.TopVolumeBranchVolume);
|
||||
outputDataSets[b->LocalBlockNo].AddField(TopVolBranchVolumeField);
|
||||
vtkm::cont::Field TopVolBranchSaddleEpsilonField("TopVolumeBranchSaddleEpsilon",
|
||||
vtkm::cont::Field::Association::WholeDataSet,
|
||||
b->TopVolumeBranchSaddleEpsilon);
|
||||
b->tData.TopVolumeBranchSaddleEpsilon);
|
||||
outputDataSets[b->LocalBlockNo].AddField(TopVolBranchSaddleEpsilonField);
|
||||
|
||||
vtkm::cont::Field IsosurfaceEdgeFromField(
|
||||
@ -243,7 +243,7 @@ VTKM_CONT vtkm::cont::PartitionedDataSet SelectTopVolumeContoursFilter::DoExecut
|
||||
"TopVolumeBranchSaddleIsoValue", vtkm::cont::Field::Association::WholeDataSet, inArray);
|
||||
outputDataSets[b->LocalBlockNo].AddField(TopVolBranchSaddleIsoValueField);
|
||||
};
|
||||
b->TopVolumeBranchSaddleIsoValue
|
||||
b->tData.TopVolumeBranchSaddleIsoValue
|
||||
.CastAndCallForTypes<vtkm::TypeListScalarAll, vtkm::cont::StorageListBasic>(resolveArray);
|
||||
});
|
||||
|
||||
|
@ -73,9 +73,9 @@ public:
|
||||
this->isMarchingCubes = marchingCubes;
|
||||
}
|
||||
|
||||
VTKM_CONT const vtkm::Id GetSavedBranches() { return this->nSavedBranches; }
|
||||
VTKM_CONT const bool GetMarchingCubes() { return this->isMarchingCubes; }
|
||||
VTKM_CONT const vtkm::cont::LogLevel GetTimingsLogLevel() { return this->TimingsLogLevel; }
|
||||
VTKM_CONT vtkm::Id GetSavedBranches() { return this->nSavedBranches; }
|
||||
VTKM_CONT bool GetMarchingCubes() { return this->isMarchingCubes; }
|
||||
VTKM_CONT vtkm::cont::LogLevel GetTimingsLogLevel() { return this->TimingsLogLevel; }
|
||||
|
||||
private:
|
||||
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet&) override;
|
||||
|
@ -97,7 +97,7 @@ void ParentBranchIsoValueFunctor::operator()(SelectTopVolumeContoursBlock* b,
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Info,
|
||||
"Block " << b->GlobalBlockId << " enqueue to Block " << target.gid);
|
||||
#endif
|
||||
auto extraMaximaBranchOrderPortal = b->ExtraMaximaBranchOrder.ReadPortal();
|
||||
auto extraMaximaBranchOrderPortal = b->tData.ExtraMaximaBranchOrder.ReadPortal();
|
||||
vtkm::Id nExtraMaxBranches = extraMaximaBranchOrderPortal.GetNumberOfValues();
|
||||
rp.enqueue(target, nExtraMaxBranches);
|
||||
|
||||
@ -112,14 +112,14 @@ void ParentBranchIsoValueFunctor::operator()(SelectTopVolumeContoursBlock* b,
|
||||
for (vtkm::Id branch = 0; branch < nExtraMaxBranches; ++branch)
|
||||
rp.enqueue<ValueType>(target, extraMaxBranchIsoValuePortal.Get(branch));
|
||||
};
|
||||
if (b->ExtraMaximaBranchIsoValue.GetNumberOfValues())
|
||||
b->ExtraMaximaBranchIsoValue
|
||||
if (b->tData.ExtraMaximaBranchIsoValue.GetNumberOfValues())
|
||||
b->tData.ExtraMaximaBranchIsoValue
|
||||
.CastAndCallForTypes<vtkm::TypeListScalarAll, vtkm::cont::StorageListBasic>(
|
||||
resolveMaxArray);
|
||||
// rp.enqueue(target, b->ExtraMaximaBranchOrder);
|
||||
// rp.enqueue(target, b->ExtraMaximaBranchIsoValue);
|
||||
// rp.enqueue(target, b->tData.ExtraMaximaBranchOrder);
|
||||
// rp.enqueue(target, b->tData.ExtraMaximaBranchIsoValue);
|
||||
|
||||
auto extraMinimaBranchOrderPortal = b->ExtraMinimaBranchOrder.ReadPortal();
|
||||
auto extraMinimaBranchOrderPortal = b->tData.ExtraMinimaBranchOrder.ReadPortal();
|
||||
vtkm::Id nExtraMinBranches = extraMinimaBranchOrderPortal.GetNumberOfValues();
|
||||
rp.enqueue(target, nExtraMinBranches);
|
||||
|
||||
@ -134,12 +134,12 @@ void ParentBranchIsoValueFunctor::operator()(SelectTopVolumeContoursBlock* b,
|
||||
for (vtkm::Id branch = 0; branch < nExtraMinBranches; ++branch)
|
||||
rp.enqueue<ValueType>(target, extraMinBranchIsoValuePortal.Get(branch));
|
||||
};
|
||||
if (b->ExtraMinimaBranchIsoValue.GetNumberOfValues())
|
||||
b->ExtraMinimaBranchIsoValue
|
||||
if (b->tData.ExtraMinimaBranchIsoValue.GetNumberOfValues())
|
||||
b->tData.ExtraMinimaBranchIsoValue
|
||||
.CastAndCallForTypes<vtkm::TypeListScalarAll, vtkm::cont::StorageListBasic>(
|
||||
resolveMinArray);
|
||||
// rp.enqueue(target, b->ExtraMinimaBranchOrder);
|
||||
// rp.enqueue(target, b->ExtraMinimaBranchIsoValue);
|
||||
// rp.enqueue(target, b->tData.ExtraMinimaBranchOrder);
|
||||
// rp.enqueue(target, b->tData.ExtraMinimaBranchIsoValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -159,8 +159,8 @@ void ParentBranchIsoValueFunctor::operator()(SelectTopVolumeContoursBlock* b,
|
||||
"Combining local block " << b->GlobalBlockId << " with incoming block "
|
||||
<< incomingGlobalBlockId);
|
||||
#endif
|
||||
vtkm::Id nSelfMaxBranch = b->ExtraMaximaBranchOrder.GetNumberOfValues();
|
||||
vtkm::Id nSelfMinBranch = b->ExtraMinimaBranchOrder.GetNumberOfValues();
|
||||
vtkm::Id nSelfMaxBranch = b->tData.ExtraMaximaBranchOrder.GetNumberOfValues();
|
||||
vtkm::Id nSelfMinBranch = b->tData.ExtraMinimaBranchOrder.GetNumberOfValues();
|
||||
|
||||
// dequeue the data from other blocks.
|
||||
// nExtraMaximaBranches (incoming)
|
||||
@ -216,7 +216,7 @@ void ParentBranchIsoValueFunctor::operator()(SelectTopVolumeContoursBlock* b,
|
||||
|
||||
vtkm::worklet::contourtree_augmented::PrintHeader(nSelfMaxBranch, rs);
|
||||
vtkm::worklet::contourtree_augmented::PrintIndices(
|
||||
"selfMaxBranchOrder", b->ExtraMaximaBranchOrder, -1, rs);
|
||||
"selfMaxBranchOrder", b->tData.ExtraMaximaBranchOrder, -1, rs);
|
||||
vtkm::worklet::contourtree_augmented::PrintValues<ValueType>(
|
||||
"selfMaxBranchVal", inArray, -1, rs);
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Info, rs.str());
|
||||
@ -227,7 +227,7 @@ void ParentBranchIsoValueFunctor::operator()(SelectTopVolumeContoursBlock* b,
|
||||
vtkm::worklet::scalar_topology::select_top_volume_contours::UpdateOuterSaddle<true>
|
||||
updateValueOnMaxBranch;
|
||||
invoke(updateValueOnMaxBranch,
|
||||
b->ExtraMaximaBranchOrder,
|
||||
b->tData.ExtraMaximaBranchOrder,
|
||||
inArray,
|
||||
incomingMaxBranchOrder,
|
||||
incomingMaxBranchIsoValue);
|
||||
@ -238,7 +238,7 @@ void ParentBranchIsoValueFunctor::operator()(SelectTopVolumeContoursBlock* b,
|
||||
rs << "After update, block " << b->LocalBlockNo << std::endl;
|
||||
vtkm::worklet::contourtree_augmented::PrintHeader(nSelfMaxBranch, rs);
|
||||
vtkm::worklet::contourtree_augmented::PrintIndices(
|
||||
"selfMaxBranchOrder", b->ExtraMaximaBranchOrder, -1, rs);
|
||||
"selfMaxBranchOrder", b->tData.ExtraMaximaBranchOrder, -1, rs);
|
||||
vtkm::worklet::contourtree_augmented::PrintValues<ValueType>(
|
||||
"selfMaxBranchVal", inArray, -1, rs);
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Info, rs.str());
|
||||
@ -246,7 +246,7 @@ void ParentBranchIsoValueFunctor::operator()(SelectTopVolumeContoursBlock* b,
|
||||
#endif
|
||||
};
|
||||
if (nSelfMaxBranch > 0 && nIncomingMaxBranch > 0)
|
||||
b->ExtraMaximaBranchIsoValue
|
||||
b->tData.ExtraMaximaBranchIsoValue
|
||||
.CastAndCallForTypes<vtkm::TypeListScalarAll, vtkm::cont::StorageListBasic>(
|
||||
resolveMaxArray);
|
||||
|
||||
@ -296,7 +296,7 @@ void ParentBranchIsoValueFunctor::operator()(SelectTopVolumeContoursBlock* b,
|
||||
|
||||
vtkm::worklet::contourtree_augmented::PrintHeader(nSelfMinBranch, rs);
|
||||
vtkm::worklet::contourtree_augmented::PrintIndices(
|
||||
"selfMinBranchOrder", b->ExtraMinimaBranchOrder, -1, rs);
|
||||
"selfMinBranchOrder", b->tData.ExtraMinimaBranchOrder, -1, rs);
|
||||
vtkm::worklet::contourtree_augmented::PrintValues<ValueType>(
|
||||
"selfMinBranchVal", inArray, -1, rs);
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Info, rs.str());
|
||||
@ -307,7 +307,7 @@ void ParentBranchIsoValueFunctor::operator()(SelectTopVolumeContoursBlock* b,
|
||||
vtkm::worklet::scalar_topology::select_top_volume_contours::UpdateOuterSaddle<false>
|
||||
updateValueOnMinBranch;
|
||||
invoke(updateValueOnMinBranch,
|
||||
b->ExtraMinimaBranchOrder,
|
||||
b->tData.ExtraMinimaBranchOrder,
|
||||
inArray,
|
||||
incomingMinBranchOrder,
|
||||
incomingMinBranchIsoValue);
|
||||
@ -318,7 +318,7 @@ void ParentBranchIsoValueFunctor::operator()(SelectTopVolumeContoursBlock* b,
|
||||
rs << "After update, block " << b->LocalBlockNo << std::endl;
|
||||
vtkm::worklet::contourtree_augmented::PrintHeader(nSelfMinBranch, rs);
|
||||
vtkm::worklet::contourtree_augmented::PrintIndices(
|
||||
"selfMinBranchOrder", b->ExtraMinimaBranchOrder, -1, rs);
|
||||
"selfMinBranchOrder", b->tData.ExtraMinimaBranchOrder, -1, rs);
|
||||
vtkm::worklet::contourtree_augmented::PrintValues<ValueType>(
|
||||
"selfMinBranchVal", inArray, -1, rs);
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Info, rs.str());
|
||||
@ -326,7 +326,7 @@ void ParentBranchIsoValueFunctor::operator()(SelectTopVolumeContoursBlock* b,
|
||||
#endif
|
||||
};
|
||||
if (nSelfMinBranch > 0 && nIncomingMinBranch > 0)
|
||||
b->ExtraMinimaBranchIsoValue
|
||||
b->tData.ExtraMinimaBranchIsoValue
|
||||
.CastAndCallForTypes<vtkm::TypeListScalarAll, vtkm::cont::StorageListBasic>(
|
||||
resolveMinArray);
|
||||
|
||||
|
@ -77,12 +77,6 @@ namespace scalar_topology
|
||||
namespace internal
|
||||
{
|
||||
|
||||
struct IsNegativeDebug
|
||||
{
|
||||
VTKM_EXEC_CONT IsNegativeDebug() {}
|
||||
VTKM_EXEC_CONT bool operator()(vtkm::Id x) const { return x < 0; }
|
||||
};
|
||||
|
||||
SelectTopVolumeContoursBlock::SelectTopVolumeContoursBlock(vtkm::Id localBlockNo, int globalBlockId)
|
||||
: LocalBlockNo(localBlockNo)
|
||||
, GlobalBlockId(globalBlockId)
|
||||
@ -161,7 +155,7 @@ void SelectTopVolumeContoursBlock::SortBranchByVolume(const vtkm::cont::DataSet&
|
||||
|
||||
vtkm::cont::ArrayHandle<ValueType> branchSaddleIsoValue;
|
||||
branchSaddleIsoValue.Allocate(isLowerLeaf.GetNumberOfValues());
|
||||
this->BranchSaddleEpsilon.Allocate(isLowerLeaf.GetNumberOfValues());
|
||||
tData.BranchSaddleEpsilon.Allocate(isLowerLeaf.GetNumberOfValues());
|
||||
|
||||
vtkm::worklet::scalar_topology::select_top_volume_contours::UpdateInfoByBranchDirectionWorklet<
|
||||
ValueType>
|
||||
@ -175,9 +169,9 @@ void SelectTopVolumeContoursBlock::SortBranchByVolume(const vtkm::cont::DataSet&
|
||||
isUpperLeaf,
|
||||
inArray,
|
||||
lowerEndValue,
|
||||
this->BranchSaddleEpsilon,
|
||||
tData.BranchSaddleEpsilon,
|
||||
branchSaddleIsoValue);
|
||||
this->BranchSaddleIsoValue = branchSaddleIsoValue;
|
||||
tData.BranchSaddleIsoValue = branchSaddleIsoValue;
|
||||
};
|
||||
|
||||
upperEndValue.CastAndCallForTypes<vtkm::TypeListScalarAll, vtkm::cont::StorageListBasic>(
|
||||
@ -224,7 +218,7 @@ void SelectTopVolumeContoursBlock::SortBranchByVolume(const vtkm::cont::DataSet&
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Info, resultStream.str());
|
||||
#endif
|
||||
|
||||
vtkm::cont::Algorithm::Copy(branchVolume, this->BranchVolume);
|
||||
vtkm::cont::Algorithm::Copy(branchVolume, tData.BranchVolume);
|
||||
|
||||
const vtkm::Id nBranches = lowerEndSuperarcId.GetNumberOfValues();
|
||||
vtkm::cont::ArrayHandleIndex branchesIdx(nBranches);
|
||||
@ -233,7 +227,7 @@ void SelectTopVolumeContoursBlock::SortBranchByVolume(const vtkm::cont::DataSet&
|
||||
|
||||
// sort the branch volume
|
||||
vtkm::cont::Algorithm::SortByKey(branchVolume, sortedBranches, vtkm::SortGreater());
|
||||
vtkm::cont::Algorithm::Copy(sortedBranches, this->SortedBranchByVolume);
|
||||
vtkm::cont::Algorithm::Copy(sortedBranches, tData.SortedBranchByVolume);
|
||||
}
|
||||
|
||||
// Select the local top K branches by volume
|
||||
@ -244,11 +238,11 @@ void SelectTopVolumeContoursBlock::SelectLocalTopVolumeBranch(const vtkm::cont::
|
||||
// copy the top volume branches into a smaller array
|
||||
// we skip index 0 because it must be the main branch (which has the highest volume)
|
||||
vtkm::Id nActualSavedBranches =
|
||||
std::min(nSavedBranches, this->SortedBranchByVolume.GetNumberOfValues() - 1);
|
||||
std::min(nSavedBranches, tData.SortedBranchByVolume.GetNumberOfValues() - 1);
|
||||
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType topVolumeBranch;
|
||||
vtkm::cont::Algorithm::CopySubRange(
|
||||
this->SortedBranchByVolume, 1, nActualSavedBranches, topVolumeBranch);
|
||||
tData.SortedBranchByVolume, 1, nActualSavedBranches, topVolumeBranch);
|
||||
|
||||
auto branchRootByBranch = bdDataset.GetField("BranchRootByBranch")
|
||||
.GetData()
|
||||
@ -268,37 +262,37 @@ void SelectTopVolumeContoursBlock::SelectLocalTopVolumeBranch(const vtkm::cont::
|
||||
.GetData()
|
||||
.AsArrayHandle<vtkm::cont::ArrayHandle<vtkm::Id>>();
|
||||
|
||||
vtkm::cont::Algorithm::Copy(branchRootByBranch, this->BranchRootByBranch);
|
||||
vtkm::cont::Algorithm::Copy(branchRootGRId, this->BranchRootGRId);
|
||||
vtkm::cont::Algorithm::Copy(branchRootByBranch, tData.BranchRootByBranch);
|
||||
vtkm::cont::Algorithm::Copy(branchRootGRId, tData.BranchRootGRId);
|
||||
|
||||
// This seems weird, but we temporarily put the initialization of computing the branch decomposition tree here
|
||||
this->IsParentBranch.AllocateAndFill(nBranches, false);
|
||||
tData.IsParentBranch.AllocateAndFill(nBranches, false);
|
||||
|
||||
// we permute all branch information to align with the order by volume
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
branchRootGRId, topVolumeBranch, this->TopVolumeBranchRootGRId);
|
||||
branchRootGRId, topVolumeBranch, tData.TopVolumeBranchRootGRId);
|
||||
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
upperEndGRId, topVolumeBranch, this->TopVolumeBranchUpperEndGRId);
|
||||
upperEndGRId, topVolumeBranch, tData.TopVolumeBranchUpperEndGRId);
|
||||
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
lowerEndGRId, topVolumeBranch, this->TopVolumeBranchLowerEndGRId);
|
||||
lowerEndGRId, topVolumeBranch, tData.TopVolumeBranchLowerEndGRId);
|
||||
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
this->BranchVolume, topVolumeBranch, this->TopVolumeBranchVolume);
|
||||
tData.BranchVolume, topVolumeBranch, tData.TopVolumeBranchVolume);
|
||||
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
this->BranchSaddleEpsilon, topVolumeBranch, this->TopVolumeBranchSaddleEpsilon);
|
||||
tData.BranchSaddleEpsilon, topVolumeBranch, tData.TopVolumeBranchSaddleEpsilon);
|
||||
|
||||
auto resolveArray = [&](const auto& inArray) {
|
||||
using InArrayHandleType = std::decay_t<decltype(inArray)>;
|
||||
InArrayHandleType topVolBranchSaddleIsoValue;
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithRawIndex<InArrayHandleType>(
|
||||
inArray, topVolumeBranch, topVolBranchSaddleIsoValue);
|
||||
this->TopVolumeBranchSaddleIsoValue = topVolBranchSaddleIsoValue;
|
||||
tData.TopVolumeBranchSaddleIsoValue = topVolBranchSaddleIsoValue;
|
||||
};
|
||||
|
||||
this->BranchSaddleIsoValue
|
||||
tData.BranchSaddleIsoValue
|
||||
.CastAndCallForTypes<vtkm::TypeListScalarAll, vtkm::cont::StorageListBasic>(resolveArray);
|
||||
}
|
||||
|
||||
@ -306,390 +300,7 @@ void SelectTopVolumeContoursBlock::SelectLocalTopVolumeBranch(const vtkm::cont::
|
||||
void SelectTopVolumeContoursBlock::ComputeTopVolumeBranchHierarchy(
|
||||
const vtkm::cont::DataSet& bdDataSet)
|
||||
{
|
||||
using vtkm::worklet::contourtree_augmented::IdArrayType;
|
||||
vtkm::cont::Invoker invoke;
|
||||
|
||||
// we need upper/lower local ends and global ends for hierarchy of branches
|
||||
auto upperLocalEndIds = bdDataSet.GetField("UpperEndLocalIds")
|
||||
.GetData()
|
||||
.AsArrayHandle<vtkm::cont::ArrayHandle<vtkm::Id>>();
|
||||
auto lowerLocalEndIds = bdDataSet.GetField("LowerEndLocalIds")
|
||||
.GetData()
|
||||
.AsArrayHandle<vtkm::cont::ArrayHandle<vtkm::Id>>();
|
||||
auto globalRegularIds = bdDataSet.GetField("RegularNodeGlobalIds")
|
||||
.GetData()
|
||||
.AsArrayHandle<vtkm::cont::ArrayHandle<vtkm::Id>>();
|
||||
IdArrayType upperEndGRIds =
|
||||
bdDataSet.GetField("UpperEndGlobalRegularIds").GetData().AsArrayHandle<IdArrayType>();
|
||||
IdArrayType lowerEndGRIds =
|
||||
bdDataSet.GetField("LowerEndGlobalRegularIds").GetData().AsArrayHandle<IdArrayType>();
|
||||
|
||||
// let's check which top volume branches are known by the block
|
||||
// We check the branchGRId of top volume branches to see whether there are matches within the block
|
||||
const vtkm::Id nTopVolBranches = this->TopVolumeBranchLowerEndGRId.GetNumberOfValues();
|
||||
|
||||
// sortedBranchOrder: the branch order (in the ascending order of branch root)
|
||||
// the high-level idea is to sort the branch root global regular ids
|
||||
// and for each top-volume branch, we use binary search to get the original branch index
|
||||
// if the top-volume branch does not exist in the block, it will be dropped out
|
||||
IdArrayType sortedBranchGRId;
|
||||
IdArrayType sortedBranchOrder;
|
||||
vtkm::cont::Algorithm::Copy(
|
||||
vtkm::cont::ArrayHandleIndex(this->BranchRootGRId.GetNumberOfValues()), sortedBranchOrder);
|
||||
vtkm::cont::Algorithm::Copy(this->BranchRootGRId, sortedBranchGRId);
|
||||
vtkm::cont::Algorithm::SortByKey(sortedBranchGRId, sortedBranchOrder);
|
||||
|
||||
this->TopVolBranchKnownByBlockStencil.Allocate(nTopVolBranches);
|
||||
this->TopVolBranchGROrder.Allocate(nTopVolBranches);
|
||||
|
||||
// We reuse the IdxIfWithinBlockWorklet.
|
||||
// This worklet searches for given values in a sorted array and returns the stencil & index if the value exists in the array.
|
||||
// this->TopVolBranchGROrder: the order of the topVolBranch among all known branches if the branch is known by the block.
|
||||
auto idxIfBranchWithinBlockWorklet =
|
||||
vtkm::worklet::scalar_topology::select_top_volume_contours::IdxIfWithinBlockWorklet();
|
||||
invoke(idxIfBranchWithinBlockWorklet,
|
||||
this->TopVolumeBranchRootGRId,
|
||||
sortedBranchGRId,
|
||||
this->TopVolBranchKnownByBlockStencil,
|
||||
this->TopVolBranchGROrder);
|
||||
|
||||
// Dropping out top-volume branches that are not known by the block.
|
||||
|
||||
// the index of top-volume branches known by the block among all top-volume branches
|
||||
IdArrayType topVolBranchKnownByBlockIndex;
|
||||
vtkm::cont::ArrayHandleIndex topVolBranchesIndex(nTopVolBranches);
|
||||
vtkm::cont::Algorithm::CopyIf(
|
||||
topVolBranchesIndex, this->TopVolBranchKnownByBlockStencil, topVolBranchKnownByBlockIndex);
|
||||
|
||||
const vtkm::Id nTopVolBranchKnownByBlock = topVolBranchKnownByBlockIndex.GetNumberOfValues();
|
||||
|
||||
// filtered this->TopVolBranchGROrder, by removing NO_SUCH_ELEMENT
|
||||
IdArrayType topVolBranchFilteredGROrder;
|
||||
|
||||
// this->TopVolBranchInfoActualIndex: the information index of the top-volume branch
|
||||
vtkm::cont::Algorithm::CopyIf(
|
||||
this->TopVolBranchGROrder, this->TopVolBranchKnownByBlockStencil, topVolBranchFilteredGROrder);
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
sortedBranchOrder, topVolBranchFilteredGROrder, this->TopVolBranchInfoActualIndex);
|
||||
|
||||
// filtered branch saddle epsilons, global lower/upper end GR ids,
|
||||
IdArrayType topVolFilteredBranchSaddleEpsilon;
|
||||
IdArrayType topVolFilteredLowerEndGRId;
|
||||
IdArrayType topVolFilteredUpperEndGRId;
|
||||
vtkm::cont::Algorithm::CopyIf(this->TopVolumeBranchSaddleEpsilon,
|
||||
this->TopVolBranchKnownByBlockStencil,
|
||||
topVolFilteredBranchSaddleEpsilon);
|
||||
vtkm::cont::Algorithm::CopyIf(this->TopVolumeBranchUpperEndGRId,
|
||||
this->TopVolBranchKnownByBlockStencil,
|
||||
topVolFilteredUpperEndGRId);
|
||||
vtkm::cont::Algorithm::CopyIf(this->TopVolumeBranchLowerEndGRId,
|
||||
this->TopVolBranchKnownByBlockStencil,
|
||||
topVolFilteredLowerEndGRId);
|
||||
|
||||
// for each top-vol branch known by the block
|
||||
// we get their upper end and lower end local ids
|
||||
IdArrayType topVolBranchUpperLocalEnd;
|
||||
IdArrayType topVolBranchLowerLocalEnd;
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
upperLocalEndIds, this->TopVolBranchInfoActualIndex, topVolBranchUpperLocalEnd);
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
lowerLocalEndIds, this->TopVolBranchInfoActualIndex, topVolBranchLowerLocalEnd);
|
||||
|
||||
IdArrayType topVolLowerLocalEndGRId;
|
||||
IdArrayType topVolUpperLocalEndGRId;
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
globalRegularIds, topVolBranchLowerLocalEnd, topVolLowerLocalEndGRId);
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
globalRegularIds, topVolBranchUpperLocalEnd, topVolUpperLocalEndGRId);
|
||||
|
||||
// Below is the code to compute the branch hierarchy of top-volume branches
|
||||
// We need this information because we not only want to visualize the contour
|
||||
// on top-volume branches, but also on their parent branches.
|
||||
// Because we use volume as the metric, the parent branch of a top-volume branch
|
||||
// is either a top-volume branch or the root branch (where both ends are leaf nodes)
|
||||
vtkm::worklet::scalar_topology::select_top_volume_contours::BranchSaddleIsKnownWorklet
|
||||
branchSaddleIsKnownWorklet;
|
||||
// the branch saddle local ID if the saddle end is known by the block
|
||||
IdArrayType branchSaddleIsKnown;
|
||||
branchSaddleIsKnown.Allocate(nTopVolBranchKnownByBlock);
|
||||
|
||||
invoke(branchSaddleIsKnownWorklet, // worklet
|
||||
topVolFilteredLowerEndGRId, // input
|
||||
topVolBranchLowerLocalEnd, // input
|
||||
topVolLowerLocalEndGRId, // input
|
||||
topVolFilteredUpperEndGRId, // input
|
||||
topVolBranchUpperLocalEnd, // input
|
||||
topVolUpperLocalEndGRId, // input
|
||||
topVolFilteredBranchSaddleEpsilon, // input
|
||||
branchSaddleIsKnown); // output
|
||||
|
||||
// the order of top volume branches with parents known by the block
|
||||
IdArrayType topVolChildBranch;
|
||||
IdArrayType topVolChildBranchSaddle;
|
||||
|
||||
vtkm::cont::Algorithm::CopyIf(
|
||||
topVolBranchKnownByBlockIndex,
|
||||
branchSaddleIsKnown,
|
||||
topVolChildBranch,
|
||||
vtkm::worklet::scalar_topology::select_top_volume_contours::IsNonNegative());
|
||||
vtkm::cont::Algorithm::CopyIf(
|
||||
branchSaddleIsKnown,
|
||||
branchSaddleIsKnown,
|
||||
topVolChildBranchSaddle,
|
||||
vtkm::worklet::scalar_topology::select_top_volume_contours::IsNonNegative());
|
||||
|
||||
const vtkm::Id nChildBranch = topVolChildBranch.GetNumberOfValues();
|
||||
|
||||
// to compute the parent branch, we need to
|
||||
// 1. for the branch saddle end, collect all superarcs involving it
|
||||
// 2. get the branch information for selected superarcs
|
||||
// 3. eliminate branch information for branches sharing the same saddle end
|
||||
|
||||
auto superarcs =
|
||||
bdDataSet.GetField("Superarcs").GetData().AsArrayHandle<vtkm::cont::ArrayHandle<vtkm::Id>>();
|
||||
auto branchRoots =
|
||||
bdDataSet.GetField("BranchRoots").GetData().AsArrayHandle<vtkm::cont::ArrayHandle<vtkm::Id>>();
|
||||
VTKM_ASSERT(superarcs.GetNumberOfValues() == branchRoots.GetNumberOfValues());
|
||||
|
||||
// we sort all superarcs by target to allow binary search
|
||||
IdArrayType superarcsByTarget;
|
||||
vtkm::worklet::scalar_topology::select_top_volume_contours::SuperarcTargetComparator
|
||||
superarcComparator(superarcs);
|
||||
vtkm::cont::Algorithm::Copy(vtkm::cont::ArrayHandleIndex(superarcs.GetNumberOfValues()),
|
||||
superarcsByTarget);
|
||||
vtkm::cont::Algorithm::Sort(superarcsByTarget, superarcComparator);
|
||||
|
||||
IdArrayType permutedSuperarcs;
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
superarcs, superarcsByTarget, permutedSuperarcs);
|
||||
|
||||
IdArrayType permutedBranchRoots;
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
branchRoots, superarcsByTarget, permutedBranchRoots);
|
||||
|
||||
// the branch root of the superarc of the branch saddle supernode
|
||||
IdArrayType topVolChildBranchSaddleBranchRoot;
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
branchRoots, topVolChildBranchSaddle, topVolChildBranchSaddleBranchRoot);
|
||||
|
||||
// the GR Ids of the superarc of the branch saddle supernode
|
||||
IdArrayType topVolChildBranchSaddleGRIds;
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
globalRegularIds, topVolChildBranchSaddle, topVolChildBranchSaddleGRIds);
|
||||
|
||||
// there is a debate to find all superarcs connect to a supernode
|
||||
// strategy 1. iterate through saddles and parallelize over superarcs for search
|
||||
// time complexity: O(nTopVolBranches)
|
||||
// (nTopVolBranches usually <= 100, based on input parameter setting)
|
||||
//
|
||||
// strategy 2. parallelize over all saddles and use binary search to find superarcs
|
||||
// time complexity: O(log_2(nSuperarcs)) (nSuperarcs can be considerably large)
|
||||
//
|
||||
// here, we choose strategy 2 for better extendability to high nTopVolBranches
|
||||
// but in tests using nTopVolBranches <= 10, strategy 1 is generally faster
|
||||
|
||||
// note: after getting the branch root superarc, we use binary search to get the branch order
|
||||
// because BranchRootByBranch is sorted by branch root (superarc) id
|
||||
|
||||
#ifdef DEBUG_PRINT
|
||||
std::stringstream parentBranchStream;
|
||||
|
||||
parentBranchStream << "Debug for Parent Branch, Block " << this->LocalBlockNo << std::endl;
|
||||
vtkm::worklet::contourtree_augmented::PrintHeader(nChildBranch, parentBranchStream);
|
||||
vtkm::worklet::contourtree_augmented::PrintIndices(
|
||||
"Child Branch Saddle", topVolChildBranchSaddle, -1, parentBranchStream);
|
||||
vtkm::worklet::contourtree_augmented::PrintIndices(
|
||||
"Child Saddle Root", topVolChildBranchSaddleBranchRoot, -1, parentBranchStream);
|
||||
vtkm::worklet::contourtree_augmented::PrintIndices(
|
||||
"Child Saddle GR Id", topVolChildBranchSaddleGRIds, -1, parentBranchStream);
|
||||
|
||||
vtkm::worklet::contourtree_augmented::PrintHeader(superarcs.GetNumberOfValues(),
|
||||
parentBranchStream);
|
||||
vtkm::worklet::contourtree_augmented::PrintIndices(
|
||||
"Permuted Superarcs", permutedSuperarcs, -1, parentBranchStream);
|
||||
vtkm::worklet::contourtree_augmented::PrintIndices(
|
||||
"Permuted Branch roots", permutedBranchRoots, -1, parentBranchStream);
|
||||
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Info, parentBranchStream.str());
|
||||
#endif // DEBUG_PRINT
|
||||
|
||||
// the corresponding parent branch of child branches
|
||||
IdArrayType topVolChildBranchParent;
|
||||
topVolChildBranchParent.AllocateAndFill(nChildBranch,
|
||||
vtkm::worklet::contourtree_augmented::NO_SUCH_ELEMENT);
|
||||
vtkm::worklet::scalar_topology::select_top_volume_contours::GetParentBranchWorklet
|
||||
getParentBranchWorklet;
|
||||
invoke(getParentBranchWorklet,
|
||||
topVolChildBranchSaddle,
|
||||
topVolChildBranchSaddleBranchRoot,
|
||||
topVolChildBranchSaddleGRIds,
|
||||
permutedSuperarcs,
|
||||
permutedBranchRoots,
|
||||
this->BranchRootByBranch,
|
||||
upperEndGRIds,
|
||||
lowerEndGRIds,
|
||||
topVolChildBranchParent);
|
||||
|
||||
this->TopVolumeBranchParent.AllocateAndFill(
|
||||
nTopVolBranches, vtkm::Id(vtkm::worklet::contourtree_augmented::NO_SUCH_ELEMENT));
|
||||
|
||||
vtkm::worklet::scalar_topology::select_top_volume_contours::AssignValueByIndex assignParentBranch;
|
||||
// for each top volume branch, assign the parent branch info id in the block
|
||||
invoke(
|
||||
assignParentBranch, topVolChildBranch, topVolChildBranchParent, this->TopVolumeBranchParent);
|
||||
// for each branch, assign true if it is a parent branch
|
||||
invoke(assignParentBranch,
|
||||
topVolChildBranchParent,
|
||||
vtkm::cont::ArrayHandleConstant<bool>(true, nChildBranch),
|
||||
this->IsParentBranch);
|
||||
|
||||
// sort all top-volume branches based on
|
||||
// 1. parent branch info id: this->TopVolumeBranchParent
|
||||
// 2. saddle-end value: this->TopVolumeBranchSaddleIsovalue
|
||||
// 3. branch root global regular id (anything that can break tie)
|
||||
auto resolveBranchParent = [&](const auto& inArray) {
|
||||
using InArrayHandleType = std::decay_t<decltype(inArray)>;
|
||||
using ValueType = typename InArrayHandleType::ValueType;
|
||||
|
||||
vtkm::worklet::scalar_topology::select_top_volume_contours::BranchParentComparator<ValueType>
|
||||
parentComparator(this->TopVolumeBranchParent, inArray, this->TopVolumeBranchRootGRId);
|
||||
|
||||
// sort index for all top volume branches
|
||||
IdArrayType topVolSortForOuterSaddleIdx;
|
||||
vtkm::cont::Algorithm::Copy(topVolBranchesIndex, topVolSortForOuterSaddleIdx);
|
||||
vtkm::cont::Algorithm::Sort(topVolSortForOuterSaddleIdx, parentComparator);
|
||||
|
||||
IdArrayType parentPermutation;
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
this->TopVolumeBranchParent, topVolSortForOuterSaddleIdx, parentPermutation);
|
||||
|
||||
// warning: when parent is NO_SUCH_ELEMENT, parentSaddleEps obtains 0
|
||||
// However, the corresponding element will be discarded in collecting outer saddles
|
||||
IdArrayType parentSaddleEpsPermutation;
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
this->BranchSaddleEpsilon, parentPermutation, parentSaddleEpsPermutation);
|
||||
|
||||
// Some branches have parent=NO_SUCH_ELEMENT (no parent)
|
||||
// we collect the isovalue of the first and/or the last branches for each parent branch
|
||||
// we collect the first if branchSaddleEpsilon(parent) < 0
|
||||
// or the last if branchSaddleEpsilon(parent) > 0
|
||||
// or both if branchSaddleEpsilon(parent) == 0
|
||||
IdArrayType IsOuterSaddle;
|
||||
IsOuterSaddle.Allocate(nTopVolBranches);
|
||||
vtkm::worklet::scalar_topology::select_top_volume_contours::CollectOuterSaddle
|
||||
collectOuterSaddleWorklet;
|
||||
invoke(collectOuterSaddleWorklet, parentSaddleEpsPermutation, parentPermutation, IsOuterSaddle);
|
||||
|
||||
// after sorting by index back
|
||||
// each top volume branch know whether it is the outer saddle of its parent
|
||||
vtkm::cont::Algorithm::SortByKey(topVolSortForOuterSaddleIdx, IsOuterSaddle);
|
||||
|
||||
// collect branches that need contours on extra minima/maxima
|
||||
// we store the information of the parent branches (on both directions)
|
||||
IdArrayType extraMaximaParentBranch;
|
||||
IdArrayType extraMinimaParentBranch;
|
||||
IdArrayType extraMaximaParentBranchRootGRId;
|
||||
IdArrayType extraMinimaParentBranchRootGRId;
|
||||
|
||||
IdArrayType allBranchGRIdByVolume;
|
||||
IdArrayType branchGRIdByVolumeIdx;
|
||||
|
||||
// we need global branch order including the root branch
|
||||
// this information should be consistent globally
|
||||
allBranchGRIdByVolume.Allocate(nTopVolBranches + 1);
|
||||
vtkm::cont::Algorithm::CopySubRange(
|
||||
this->TopVolumeBranchRootGRId, 0, nTopVolBranches, allBranchGRIdByVolume, 1);
|
||||
auto topBranchGRIdWritePortal = allBranchGRIdByVolume.WritePortal();
|
||||
auto sortedBranchByVolPortal = this->SortedBranchByVolume.ReadPortal();
|
||||
auto branchGRIdReadPortal = this->BranchRootGRId.ReadPortal();
|
||||
topBranchGRIdWritePortal.Set(0, branchGRIdReadPortal.Get(sortedBranchByVolPortal.Get(0)));
|
||||
|
||||
vtkm::cont::Algorithm::Copy(
|
||||
vtkm::cont::ArrayHandleIndex(allBranchGRIdByVolume.GetNumberOfValues()),
|
||||
branchGRIdByVolumeIdx);
|
||||
vtkm::cont::Algorithm::SortByKey(allBranchGRIdByVolume, branchGRIdByVolumeIdx);
|
||||
|
||||
vtkm::cont::Algorithm::CopyIf(
|
||||
this->TopVolumeBranchParent,
|
||||
IsOuterSaddle,
|
||||
extraMaximaParentBranch,
|
||||
vtkm::worklet::scalar_topology::select_top_volume_contours::IsExtraMaxima());
|
||||
vtkm::cont::Algorithm::CopyIf(
|
||||
this->TopVolumeBranchParent,
|
||||
IsOuterSaddle,
|
||||
extraMinimaParentBranch,
|
||||
vtkm::worklet::scalar_topology::select_top_volume_contours::IsExtraMinima());
|
||||
|
||||
if (extraMaximaParentBranch.GetNumberOfValues())
|
||||
{
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
upperLocalEndIds, extraMaximaParentBranch, this->ExtraMaximaBranchUpperEnd);
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
lowerLocalEndIds, extraMaximaParentBranch, this->ExtraMaximaBranchLowerEnd);
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
this->BranchRootGRId, extraMaximaParentBranch, extraMaximaParentBranchRootGRId);
|
||||
|
||||
InArrayHandleType extraMaximaBranchIsoValue;
|
||||
vtkm::cont::Algorithm::CopyIf(
|
||||
this->TopVolumeBranchSaddleIsoValue.AsArrayHandle<InArrayHandleType>(),
|
||||
IsOuterSaddle,
|
||||
extraMaximaBranchIsoValue,
|
||||
vtkm::worklet::scalar_topology::select_top_volume_contours::IsExtraMaxima());
|
||||
this->ExtraMaximaBranchIsoValue = extraMaximaBranchIsoValue;
|
||||
|
||||
// a worklet to binary search a number in a sorted array and return the index
|
||||
vtkm::worklet::scalar_topology::select_top_volume_contours::IdxIfWithinBlockWorklet
|
||||
getParentBranchOrder;
|
||||
IdArrayType permutedExtraMaximaBranchOrder;
|
||||
permutedExtraMaximaBranchOrder.Allocate(extraMaximaParentBranchRootGRId.GetNumberOfValues());
|
||||
vtkm::cont::ArrayHandleDiscard<vtkm::Id> discard;
|
||||
discard.Allocate(extraMaximaParentBranchRootGRId.GetNumberOfValues());
|
||||
invoke(getParentBranchOrder,
|
||||
extraMaximaParentBranchRootGRId,
|
||||
allBranchGRIdByVolume,
|
||||
discard,
|
||||
permutedExtraMaximaBranchOrder);
|
||||
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
branchGRIdByVolumeIdx, permutedExtraMaximaBranchOrder, this->ExtraMaximaBranchOrder);
|
||||
}
|
||||
|
||||
if (extraMinimaParentBranch.GetNumberOfValues())
|
||||
{
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
upperLocalEndIds, extraMinimaParentBranch, this->ExtraMinimaBranchUpperEnd);
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
lowerLocalEndIds, extraMinimaParentBranch, this->ExtraMinimaBranchLowerEnd);
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
this->BranchRootGRId, extraMinimaParentBranch, extraMinimaParentBranchRootGRId);
|
||||
|
||||
InArrayHandleType extraMinimaBranchIsoValue;
|
||||
vtkm::cont::Algorithm::CopyIf(
|
||||
this->TopVolumeBranchSaddleIsoValue.AsArrayHandle<InArrayHandleType>(),
|
||||
IsOuterSaddle,
|
||||
extraMinimaBranchIsoValue,
|
||||
vtkm::worklet::scalar_topology::select_top_volume_contours::IsExtraMinima());
|
||||
this->ExtraMinimaBranchIsoValue = extraMinimaBranchIsoValue;
|
||||
|
||||
vtkm::worklet::scalar_topology::select_top_volume_contours::IdxIfWithinBlockWorklet
|
||||
getParentBranchOrder;
|
||||
IdArrayType permutedExtraMinimaBranchOrder;
|
||||
permutedExtraMinimaBranchOrder.Allocate(extraMinimaParentBranchRootGRId.GetNumberOfValues());
|
||||
vtkm::cont::ArrayHandleDiscard<vtkm::Id> discard;
|
||||
discard.Allocate(extraMinimaParentBranchRootGRId.GetNumberOfValues());
|
||||
invoke(getParentBranchOrder,
|
||||
extraMinimaParentBranchRootGRId,
|
||||
allBranchGRIdByVolume,
|
||||
discard,
|
||||
permutedExtraMinimaBranchOrder);
|
||||
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
branchGRIdByVolumeIdx, permutedExtraMinimaBranchOrder, this->ExtraMinimaBranchOrder);
|
||||
}
|
||||
};
|
||||
this->TopVolumeBranchSaddleIsoValue
|
||||
.CastAndCallForTypes<vtkm::TypeListScalarAll, vtkm::cont::StorageListBasic>(
|
||||
resolveBranchParent);
|
||||
this->bdtMaker.ComputeTopVolumeBranchHierarchy(bdDataSet, this->tData);
|
||||
}
|
||||
|
||||
|
||||
@ -701,7 +312,7 @@ void SelectTopVolumeContoursBlock::ExtractIsosurfaceOnSelectedBranch(
|
||||
using vtkm::worklet::contourtree_augmented::IdArrayType;
|
||||
|
||||
// if no branch to extract from
|
||||
if (this->TopVolumeBranchRootGRId.GetNumberOfValues() < 1)
|
||||
if (tData.TopVolumeBranchRootGRId.GetNumberOfValues() < 1)
|
||||
return;
|
||||
|
||||
// Let's create a mesh dataset to extract all the contours first
|
||||
@ -711,7 +322,7 @@ void SelectTopVolumeContoursBlock::ExtractIsosurfaceOnSelectedBranch(
|
||||
// usage: identifier of the branch
|
||||
vtkm::cont::Algorithm::Copy(
|
||||
bdDataSet.GetField("BranchRootGRId").GetData().AsArrayHandle<IdArrayType>(),
|
||||
this->BranchRootGRId);
|
||||
tData.BranchRootGRId);
|
||||
|
||||
// branch local upper end and lower end
|
||||
// size: nBranches
|
||||
@ -893,7 +504,7 @@ void SelectTopVolumeContoursBlock::ExtractIsosurfaceOnSelectedBranch(
|
||||
|
||||
IdArrayType topVolBranchWithinBlockId;
|
||||
vtkm::cont::Algorithm::CopyIf(vtkm::cont::ArrayHandleIndex(nIsoValues),
|
||||
this->TopVolBranchKnownByBlockStencil,
|
||||
tData.TopVolBranchKnownByBlockStencil,
|
||||
topVolBranchWithinBlockId);
|
||||
auto topVolBranchWithinBlockIdPortal = topVolBranchWithinBlockId.ReadPortal();
|
||||
|
||||
@ -901,13 +512,13 @@ void SelectTopVolumeContoursBlock::ExtractIsosurfaceOnSelectedBranch(
|
||||
|
||||
// filtered branch saddle values
|
||||
InArrayHandleType isoValues;
|
||||
vtkm::cont::Algorithm::CopyIf(inArray, this->TopVolBranchKnownByBlockStencil, isoValues);
|
||||
vtkm::cont::Algorithm::CopyIf(inArray, tData.TopVolBranchKnownByBlockStencil, isoValues);
|
||||
auto isoValuePortal = isoValues.ReadPortal();
|
||||
|
||||
// filtered branch saddle epsilons
|
||||
IdArrayType topVolBranchSaddleEpsilons;
|
||||
vtkm::cont::Algorithm::CopyIf(this->TopVolumeBranchSaddleEpsilon,
|
||||
this->TopVolBranchKnownByBlockStencil,
|
||||
vtkm::cont::Algorithm::CopyIf(tData.TopVolumeBranchSaddleEpsilon,
|
||||
tData.TopVolBranchKnownByBlockStencil,
|
||||
topVolBranchSaddleEpsilons);
|
||||
auto topVolBranchSaddleEpsilonPortal = topVolBranchSaddleEpsilons.ReadPortal();
|
||||
|
||||
@ -917,11 +528,11 @@ void SelectTopVolumeContoursBlock::ExtractIsosurfaceOnSelectedBranch(
|
||||
IdArrayType topVolLocalBranchLowerEnd;
|
||||
vtkm::cont::ArrayHandle<bool> topVolIsParent;
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
upperEndLocalIds, this->TopVolBranchInfoActualIndex, topVolLocalBranchUpperEnd);
|
||||
upperEndLocalIds, tData.TopVolBranchInfoActualIndex, topVolLocalBranchUpperEnd);
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
lowerEndLocalIds, this->TopVolBranchInfoActualIndex, topVolLocalBranchLowerEnd);
|
||||
lowerEndLocalIds, tData.TopVolBranchInfoActualIndex, topVolLocalBranchLowerEnd);
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithRawIndex<vtkm::cont::ArrayHandle<bool>>(
|
||||
this->IsParentBranch, this->TopVolBranchInfoActualIndex, topVolIsParent);
|
||||
tData.IsParentBranch, tData.TopVolBranchInfoActualIndex, topVolIsParent);
|
||||
auto topVolIsParentPortal = topVolIsParent.ReadPortal();
|
||||
|
||||
// we compute the superarc of the branch within the block
|
||||
@ -948,7 +559,7 @@ void SelectTopVolumeContoursBlock::ExtractIsosurfaceOnSelectedBranch(
|
||||
vtkm::worklet::contourtree_augmented::PrintHeader(sortedBranchGRId.GetNumberOfValues(),
|
||||
branchStream);
|
||||
vtkm::worklet::contourtree_augmented::PrintIndices(
|
||||
"Raw Branch GR", this->BranchRootGRId, -1, branchStream);
|
||||
"Raw Branch GR", tData.BranchRootGRId, -1, branchStream);
|
||||
vtkm::worklet::contourtree_augmented::PrintIndices(
|
||||
"Raw Upper End", upperLocalEndIds, -1, branchStream);
|
||||
vtkm::worklet::contourtree_augmented::PrintIndices(
|
||||
@ -960,7 +571,7 @@ void SelectTopVolumeContoursBlock::ExtractIsosurfaceOnSelectedBranch(
|
||||
|
||||
vtkm::worklet::contourtree_augmented::PrintHeader(nIsoValues, branchStream);
|
||||
vtkm::worklet::contourtree_augmented::PrintIndices(
|
||||
"Top Branch GR", this->TopVolumeBranchRootGRId, -1, branchStream);
|
||||
"Top Branch GR", tData.TopVolumeBranchRootGRId, -1, branchStream);
|
||||
vtkm::worklet::contourtree_augmented::PrintIndices(
|
||||
"Top Branch Stencil", topVolBranchWithinBlockStencil, -1, branchStream);
|
||||
vtkm::worklet::contourtree_augmented::PrintIndices(
|
||||
@ -975,8 +586,8 @@ void SelectTopVolumeContoursBlock::ExtractIsosurfaceOnSelectedBranch(
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Info, branchStream.str());
|
||||
#endif
|
||||
|
||||
const vtkm::Id nExtraMaximaBranch = this->ExtraMaximaBranchLowerEnd.GetNumberOfValues();
|
||||
const vtkm::Id nExtraMinimaBranch = this->ExtraMinimaBranchLowerEnd.GetNumberOfValues();
|
||||
const vtkm::Id nExtraMaximaBranch = tData.ExtraMaximaBranchLowerEnd.GetNumberOfValues();
|
||||
const vtkm::Id nExtraMinimaBranch = tData.ExtraMinimaBranchLowerEnd.GetNumberOfValues();
|
||||
InArrayHandleType extraMaximaBranchIsoValue;
|
||||
InArrayHandleType extraMinimaBranchIsoValue;
|
||||
|
||||
@ -988,11 +599,11 @@ void SelectTopVolumeContoursBlock::ExtractIsosurfaceOnSelectedBranch(
|
||||
if (nExtraMaximaBranch)
|
||||
{
|
||||
extraMaximaBranchIsoValue =
|
||||
this->ExtraMaximaBranchIsoValue.AsArrayHandle<InArrayHandleType>();
|
||||
tData.ExtraMaximaBranchIsoValue.AsArrayHandle<InArrayHandleType>();
|
||||
|
||||
invoke(branchIsoSuperarcWorklet,
|
||||
this->ExtraMaximaBranchUpperEnd,
|
||||
this->ExtraMaximaBranchLowerEnd,
|
||||
tData.ExtraMaximaBranchUpperEnd,
|
||||
tData.ExtraMaximaBranchLowerEnd,
|
||||
extraMaximaBranchIsoValue,
|
||||
vtkm::cont::ArrayHandleConstant<vtkm::Id>(1, nExtraMaximaBranch),
|
||||
extraMaximaBranchSuperarcs,
|
||||
@ -1003,15 +614,15 @@ void SelectTopVolumeContoursBlock::ExtractIsosurfaceOnSelectedBranch(
|
||||
extraMaxStream << "Debug for Extra Maxima Branch, Block " << this->LocalBlockNo << std::endl;
|
||||
vtkm::worklet::contourtree_augmented::PrintHeader(nExtraMaximaBranch, extraMaxStream);
|
||||
vtkm::worklet::contourtree_augmented::PrintIndices(
|
||||
"Max Branch Upper End", this->ExtraMaximaBranchUpperEnd, -1, extraMaxStream);
|
||||
"Max Branch Upper End", tData.ExtraMaximaBranchUpperEnd, -1, extraMaxStream);
|
||||
vtkm::worklet::contourtree_augmented::PrintIndices(
|
||||
"Max Branch Lower End", this->ExtraMaximaBranchLowerEnd, -1, extraMaxStream);
|
||||
"Max Branch Lower End", tData.ExtraMaximaBranchLowerEnd, -1, extraMaxStream);
|
||||
vtkm::worklet::contourtree_augmented::PrintValues<ValueType>(
|
||||
"Max Branch IsoValue", extraMaximaBranchIsoValue, -1, extraMaxStream);
|
||||
vtkm::worklet::contourtree_augmented::PrintIndices(
|
||||
"Max Branch Superarc", extraMaximaBranchSuperarcs, -1, extraMaxStream);
|
||||
vtkm::worklet::contourtree_augmented::PrintIndices(
|
||||
"Max Branch Order", this->ExtraMaximaBranchOrder, -1, extraMaxStream);
|
||||
"Max Branch Order", tData.ExtraMaximaBranchOrder, -1, extraMaxStream);
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Info, extraMaxStream.str());
|
||||
#endif // DEBUG_PRINT
|
||||
}
|
||||
@ -1019,11 +630,11 @@ void SelectTopVolumeContoursBlock::ExtractIsosurfaceOnSelectedBranch(
|
||||
if (nExtraMinimaBranch)
|
||||
{
|
||||
extraMinimaBranchIsoValue =
|
||||
this->ExtraMinimaBranchIsoValue.AsArrayHandle<InArrayHandleType>();
|
||||
tData.ExtraMinimaBranchIsoValue.AsArrayHandle<InArrayHandleType>();
|
||||
|
||||
invoke(branchIsoSuperarcWorklet,
|
||||
this->ExtraMinimaBranchUpperEnd,
|
||||
this->ExtraMinimaBranchLowerEnd,
|
||||
tData.ExtraMinimaBranchUpperEnd,
|
||||
tData.ExtraMinimaBranchLowerEnd,
|
||||
extraMinimaBranchIsoValue,
|
||||
vtkm::cont::ArrayHandleConstant<vtkm::Id>(-1, nExtraMinimaBranch),
|
||||
extraMinimaBranchSuperarcs,
|
||||
@ -1034,15 +645,15 @@ void SelectTopVolumeContoursBlock::ExtractIsosurfaceOnSelectedBranch(
|
||||
extraMaxStream << "Debug for Extra Maxima Branch, Block " << this->LocalBlockNo << std::endl;
|
||||
vtkm::worklet::contourtree_augmented::PrintHeader(nExtraMinimaBranch, extraMinStream);
|
||||
vtkm::worklet::contourtree_augmented::PrintIndices(
|
||||
"Max Branch Upper End", this->ExtraMinimaBranchUpperEnd, -1, extraMinStream);
|
||||
"Max Branch Upper End", tData.ExtraMinimaBranchUpperEnd, -1, extraMinStream);
|
||||
vtkm::worklet::contourtree_augmented::PrintIndices(
|
||||
"Max Branch Lower End", this->ExtraMinimaBranchLowerEnd, -1, extraMinStream);
|
||||
"Max Branch Lower End", tData.ExtraMinimaBranchLowerEnd, -1, extraMinStream);
|
||||
vtkm::worklet::contourtree_augmented::PrintValues<ValueType>(
|
||||
"Max Branch IsoValue", extraMinimaBranchIsoValue, -1, extraMinStream);
|
||||
vtkm::worklet::contourtree_augmented::PrintIndices(
|
||||
"Max Branch Superarc", extraMinimaBranchSuperarcs, -1, extraMinStream);
|
||||
vtkm::worklet::contourtree_augmented::PrintIndices(
|
||||
"Max Branch Order", this->ExtraMinimaBranchOrder, -1, extraMinStream);
|
||||
"Max Branch Order", tData.ExtraMinimaBranchOrder, -1, extraMinStream);
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Info, extraMinStream.str());
|
||||
#endif // DEBUG_PRINT
|
||||
}
|
||||
@ -1051,8 +662,8 @@ void SelectTopVolumeContoursBlock::ExtractIsosurfaceOnSelectedBranch(
|
||||
auto extraMinimaBranchSuperarcPortal = extraMinimaBranchSuperarcs.ReadPortal();
|
||||
auto extraMaximaBranchIsoValuePortal = extraMaximaBranchIsoValue.ReadPortal();
|
||||
auto extraMinimaBranchIsoValuePortal = extraMinimaBranchIsoValue.ReadPortal();
|
||||
auto extraMaximaBranchOrderPortal = this->ExtraMaximaBranchOrder.ReadPortal();
|
||||
auto extraMinimaBranchOrderPortal = this->ExtraMinimaBranchOrder.ReadPortal();
|
||||
auto extraMaximaBranchOrderPortal = tData.ExtraMaximaBranchOrder.ReadPortal();
|
||||
auto extraMinimaBranchOrderPortal = tData.ExtraMinimaBranchOrder.ReadPortal();
|
||||
|
||||
const vtkm::Id nContours = nTopVolBranchWithinBlock + nExtraMaximaBranch + nExtraMinimaBranch;
|
||||
this->IsosurfaceEdgesOffset.AllocateAndFill(nContours, 0);
|
||||
@ -1295,7 +906,7 @@ void SelectTopVolumeContoursBlock::ExtractIsosurfaceOnSelectedBranch(
|
||||
<< " " << std::setw(60) << std::left
|
||||
<< "Number of Meshes On Branches: " << nMeshesOnBranches << std::endl);
|
||||
};
|
||||
this->TopVolumeBranchSaddleIsoValue
|
||||
tData.TopVolumeBranchSaddleIsoValue
|
||||
.CastAndCallForTypes<vtkm::TypeListScalarAll, vtkm::cont::StorageListBasic>(resolveArray);
|
||||
}
|
||||
|
||||
|
@ -55,6 +55,8 @@
|
||||
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
#include <vtkm/filter/scalar_topology/worklet/contourtree_augmented/Types.h>
|
||||
#include <vtkm/filter/scalar_topology/worklet/select_top_volume_contours/TopVolumeBranchData.h>
|
||||
#include <vtkm/filter/scalar_topology/worklet/select_top_volume_contours/BranchDecompositionTreeMaker.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
@ -69,65 +71,54 @@ struct SelectTopVolumeContoursBlock
|
||||
{
|
||||
SelectTopVolumeContoursBlock(vtkm::Id localBlockNo, int globalBlockId);
|
||||
|
||||
void SortBranchByVolume(const vtkm::cont::DataSet& bdDataSet, const vtkm::Id totalVolume);
|
||||
|
||||
void SelectLocalTopVolumeBranch(const vtkm::cont::DataSet& bdDataSet,
|
||||
const vtkm::Id nSavedBranches);
|
||||
|
||||
void ComputeTopVolumeBranchHierarchy(const vtkm::cont::DataSet& bdDataSet);
|
||||
|
||||
void ExtractIsosurfaceOnSelectedBranch(const vtkm::cont::DataSet& bdDataSet,
|
||||
const bool isMarchingCubes,
|
||||
const vtkm::cont::LogLevel timingsLogLevel);
|
||||
|
||||
// Block metadata
|
||||
vtkm::Id LocalBlockNo;
|
||||
int GlobalBlockId; // TODO/FIXME: Check whether really needed. Possibly only during debugging
|
||||
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType BranchRootByBranch;
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType BranchRootGRId;
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType BranchVolume;
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType BranchSaddleEpsilon;
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType SortedBranchByVolume;
|
||||
vtkm::cont::ArrayHandle<bool> IsParentBranch;
|
||||
vtkm::cont::UnknownArrayHandle BranchSaddleIsoValue;
|
||||
TopVolumeBranchData tData;
|
||||
|
||||
// Output Datasets.
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType TopVolumeBranchRoot;
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType TopVolumeBranchRootGRId;
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType TopVolumeBranchVolume;
|
||||
// the parent branch of top volume branches (if no parent branch, then NO_SUCH_ELEMENT)
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType TopVolumeBranchParent;
|
||||
vtkm::cont::UnknownArrayHandle TopVolumeBranchSaddleIsoValue;
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType TopVolumeBranchSaddleEpsilon;
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType TopVolumeBranchUpperEndGRId;
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType TopVolumeBranchLowerEndGRId;
|
||||
// the factory class to compute the relation of top-volume branches
|
||||
BranchDecompositionTreeMaker bdtMaker;
|
||||
|
||||
// Other top-volume branch information
|
||||
|
||||
// whether the top volume branch is known by the block
|
||||
// size: nTopVolBranches
|
||||
// value range: [0, 1]
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType TopVolBranchKnownByBlockStencil;
|
||||
// the branch order (among all branches) by branch root global regular ids
|
||||
// size: nTopVolBranches
|
||||
// value range: {NO_SUCH_ELEMENT} U [0, nBranches - 1]
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType TopVolBranchGROrder;
|
||||
// the branch information index (known by the block) of the top volume branch
|
||||
// size: nTopVolBranchKnownByBlock
|
||||
// value range: [0, nBranches - 1]
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType TopVolBranchInfoActualIndex;
|
||||
|
||||
// information to extract extra isosurface for extrema
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType ExtraMaximaBranchUpperEnd;
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType ExtraMaximaBranchLowerEnd;
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType ExtraMaximaBranchOrder;
|
||||
vtkm::cont::UnknownArrayHandle ExtraMaximaBranchIsoValue;
|
||||
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType ExtraMinimaBranchUpperEnd;
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType ExtraMinimaBranchLowerEnd;
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType ExtraMinimaBranchOrder;
|
||||
vtkm::cont::UnknownArrayHandle ExtraMinimaBranchIsoValue;
|
||||
//vtkm::worklet::contourtree_augmented::IdArrayType BranchRootByBranch;
|
||||
//vtkm::worklet::contourtree_augmented::IdArrayType BranchRootGRId;
|
||||
//vtkm::worklet::contourtree_augmented::IdArrayType BranchVolume;
|
||||
//vtkm::worklet::contourtree_augmented::IdArrayType BranchSaddleEpsilon;
|
||||
//vtkm::worklet::contourtree_augmented::IdArrayType SortedBranchByVolume;
|
||||
//vtkm::cont::ArrayHandle<bool> IsParentBranch;
|
||||
//vtkm::cont::UnknownArrayHandle BranchSaddleIsoValue;
|
||||
//// Output Datasets.
|
||||
//vtkm::worklet::contourtree_augmented::IdArrayType TopVolumeBranchRoot;
|
||||
//vtkm::worklet::contourtree_augmented::IdArrayType TopVolumeBranchRootGRId;
|
||||
//vtkm::worklet::contourtree_augmented::IdArrayType TopVolumeBranchVolume;
|
||||
//// the parent branch of top volume branches (if no parent branch, then NO_SUCH_ELEMENT)
|
||||
//vtkm::worklet::contourtree_augmented::IdArrayType TopVolumeBranchParent;
|
||||
//vtkm::cont::UnknownArrayHandle TopVolumeBranchSaddleIsoValue;
|
||||
//vtkm::worklet::contourtree_augmented::IdArrayType TopVolumeBranchSaddleEpsilon;
|
||||
//vtkm::worklet::contourtree_augmented::IdArrayType TopVolumeBranchUpperEndGRId;
|
||||
//vtkm::worklet::contourtree_augmented::IdArrayType TopVolumeBranchLowerEndGRId;
|
||||
//// Other top-volume branch information
|
||||
//// whether the top volume branch is known by the block
|
||||
//// size: nTopVolBranches
|
||||
//// value range: [0, 1]
|
||||
//vtkm::worklet::contourtree_augmented::IdArrayType TopVolBranchKnownByBlockStencil;
|
||||
//// the branch order (among all branches) by branch root global regular ids
|
||||
//// size: nTopVolBranches
|
||||
//// value range: {NO_SUCH_ELEMENT} U [0, nBranches - 1]
|
||||
//vtkm::worklet::contourtree_augmented::IdArrayType TopVolBranchGROrder;
|
||||
//// the branch information index (known by the block) of the top volume branch
|
||||
//// size: nTopVolBranchKnownByBlock
|
||||
//// value range: [0, nBranches - 1]
|
||||
//vtkm::worklet::contourtree_augmented::IdArrayType TopVolBranchInfoActualIndex;
|
||||
//// information to extract extra isosurface for extrema
|
||||
//vtkm::worklet::contourtree_augmented::IdArrayType ExtraMaximaBranchUpperEnd;
|
||||
//vtkm::worklet::contourtree_augmented::IdArrayType ExtraMaximaBranchLowerEnd;
|
||||
//vtkm::worklet::contourtree_augmented::IdArrayType ExtraMaximaBranchOrder;
|
||||
//vtkm::cont::UnknownArrayHandle ExtraMaximaBranchIsoValue;
|
||||
//vtkm::worklet::contourtree_augmented::IdArrayType ExtraMinimaBranchUpperEnd;
|
||||
//vtkm::worklet::contourtree_augmented::IdArrayType ExtraMinimaBranchLowerEnd;
|
||||
//vtkm::worklet::contourtree_augmented::IdArrayType ExtraMinimaBranchOrder;
|
||||
//vtkm::cont::UnknownArrayHandle ExtraMinimaBranchIsoValue;
|
||||
|
||||
// Isosurface output
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec3f_64> IsosurfaceEdgesFrom;
|
||||
@ -139,6 +130,17 @@ struct SelectTopVolumeContoursBlock
|
||||
|
||||
// Destroy function allowing DIY to own blocks and clean them up after use
|
||||
static void Destroy(void* b) { delete static_cast<SelectTopVolumeContoursBlock*>(b); }
|
||||
|
||||
void SortBranchByVolume(const vtkm::cont::DataSet& bdDataSet, const vtkm::Id totalVolume);
|
||||
|
||||
void SelectLocalTopVolumeBranch(const vtkm::cont::DataSet& bdDataSet,
|
||||
const vtkm::Id nSavedBranches);
|
||||
|
||||
void ComputeTopVolumeBranchHierarchy(const vtkm::cont::DataSet& bdDataSet);
|
||||
|
||||
void ExtractIsosurfaceOnSelectedBranch(const vtkm::cont::DataSet& bdDataSet,
|
||||
const bool isMarchingCubes,
|
||||
const vtkm::cont::LogLevel timingsLogLevel);
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
@ -101,11 +101,11 @@ void SelectTopVolumeContoursFunctor::operator()(
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Info,
|
||||
"Block " << b->GlobalBlockId << " enqueue to Block " << target.gid);
|
||||
#endif
|
||||
auto topVolBranchRootGRIdPortal = b->TopVolumeBranchRootGRId.ReadPortal();
|
||||
auto topVolBranchVolumePortal = b->TopVolumeBranchVolume.ReadPortal();
|
||||
auto topVolBranchSaddleEpsilonPortal = b->TopVolumeBranchSaddleEpsilon.ReadPortal();
|
||||
auto topVolBranchUpperEndPortal = b->TopVolumeBranchUpperEndGRId.ReadPortal();
|
||||
auto topVolBranchLowerEndPortal = b->TopVolumeBranchLowerEndGRId.ReadPortal();
|
||||
auto topVolBranchRootGRIdPortal = b->tData.TopVolumeBranchRootGRId.ReadPortal();
|
||||
auto topVolBranchVolumePortal = b->tData.TopVolumeBranchVolume.ReadPortal();
|
||||
auto topVolBranchSaddleEpsilonPortal = b->tData.TopVolumeBranchSaddleEpsilon.ReadPortal();
|
||||
auto topVolBranchUpperEndPortal = b->tData.TopVolumeBranchUpperEndGRId.ReadPortal();
|
||||
auto topVolBranchLowerEndPortal = b->tData.TopVolumeBranchLowerEndGRId.ReadPortal();
|
||||
|
||||
vtkm::Id nBranches = topVolBranchRootGRIdPortal.GetNumberOfValues();
|
||||
|
||||
@ -128,11 +128,11 @@ void SelectTopVolumeContoursFunctor::operator()(
|
||||
for (vtkm::Id branch = 0; branch < nBranches; ++branch)
|
||||
rp.enqueue<ValueType>(target, topVolBranchSaddleIsoValuePortal.Get(branch));
|
||||
};
|
||||
b->TopVolumeBranchSaddleIsoValue
|
||||
b->tData.TopVolumeBranchSaddleIsoValue
|
||||
.CastAndCallForTypes<vtkm::TypeListScalarAll, vtkm::cont::StorageListBasic>(resolveArray);
|
||||
|
||||
// rp.enqueue(target, b->TopVolumeBranchRootGRId);
|
||||
// rp.enqueue(target, b->TopVolumeBranchVolume);
|
||||
// rp.enqueue(target, b->tData.TopVolumeBranchRootGRId);
|
||||
// rp.enqueue(target, b->tData.TopVolumeBranchVolume);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -267,7 +267,7 @@ void SelectTopVolumeContoursFunctor::operator()(
|
||||
// Replace with dequeuing ArrayHandles once bug is fixed.
|
||||
// rp.dequeue<InArrayHandleType>(ingid, incomingTopVolBranchSaddleIsoValue);
|
||||
|
||||
vtkm::Id nSelf = b->TopVolumeBranchRootGRId.GetNumberOfValues();
|
||||
vtkm::Id nSelf = b->tData.TopVolumeBranchRootGRId.GetNumberOfValues();
|
||||
|
||||
#ifdef DEBUG_PRINT_COMBINED_HIGH_VOLUME_BRANCH
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Info,
|
||||
@ -288,15 +288,15 @@ void SelectTopVolumeContoursFunctor::operator()(
|
||||
|
||||
vtkm::worklet::contourtree_augmented::PrintHeader(nSelf, rs);
|
||||
vtkm::worklet::contourtree_augmented::PrintIndices(
|
||||
"selfTopBranchId", b->TopVolumeBranchRootGRId, -1, rs);
|
||||
"selfTopBranchId", b->tData.TopVolumeBranchRootGRId, -1, rs);
|
||||
vtkm::worklet::contourtree_augmented::PrintIndices(
|
||||
"selfTopBranchVol", b->TopVolumeBranchVolume, -1, rs);
|
||||
"selfTopBranchVol", b->tData.TopVolumeBranchVolume, -1, rs);
|
||||
vtkm::worklet::contourtree_augmented::PrintValues<ValueType>(
|
||||
"selfTopSaddleVal", inArray, -1, rs);
|
||||
vtkm::worklet::contourtree_augmented::PrintIndices(
|
||||
"selfTopBranchUpperEnd", b->TopVolumeBranchUpperEndGRId, -1, rs);
|
||||
"selfTopBranchUpperEnd", b->tData.TopVolumeBranchUpperEndGRId, -1, rs);
|
||||
vtkm::worklet::contourtree_augmented::PrintIndices(
|
||||
"selfTopBranchLowerEnd", b->TopVolumeBranchLowerEndGRId, -1, rs);
|
||||
"selfTopBranchLowerEnd", b->tData.TopVolumeBranchLowerEndGRId, -1, rs);
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Info, rs.str());
|
||||
}
|
||||
#endif
|
||||
@ -327,15 +327,15 @@ void SelectTopVolumeContoursFunctor::operator()(
|
||||
vtkm::cont::Algorithm::CopySubRange<ValueType, ValueType>(
|
||||
incomingTopVolBranchSaddleIsoValue, 0, nIncoming, mergedTopVolBranchSaddleIsoValue, 0);
|
||||
vtkm::cont::Algorithm::CopySubRange(
|
||||
b->TopVolumeBranchRootGRId, 0, nSelf, mergedTopVolBranchGRId, nIncoming);
|
||||
b->tData.TopVolumeBranchRootGRId, 0, nSelf, mergedTopVolBranchGRId, nIncoming);
|
||||
vtkm::cont::Algorithm::CopySubRange(
|
||||
b->TopVolumeBranchVolume, 0, nSelf, mergedTopVolBranchVolume, nIncoming);
|
||||
b->tData.TopVolumeBranchVolume, 0, nSelf, mergedTopVolBranchVolume, nIncoming);
|
||||
vtkm::cont::Algorithm::CopySubRange(
|
||||
b->TopVolumeBranchSaddleEpsilon, 0, nSelf, mergedTopVolBranchSaddleEpsilon, nIncoming);
|
||||
b->tData.TopVolumeBranchSaddleEpsilon, 0, nSelf, mergedTopVolBranchSaddleEpsilon, nIncoming);
|
||||
vtkm::cont::Algorithm::CopySubRange(
|
||||
b->TopVolumeBranchUpperEndGRId, 0, nSelf, mergedTopVolBranchUpperEnd, nIncoming);
|
||||
b->tData.TopVolumeBranchUpperEndGRId, 0, nSelf, mergedTopVolBranchUpperEnd, nIncoming);
|
||||
vtkm::cont::Algorithm::CopySubRange(
|
||||
b->TopVolumeBranchLowerEndGRId, 0, nSelf, mergedTopVolBranchLowerEnd, nIncoming);
|
||||
b->tData.TopVolumeBranchLowerEndGRId, 0, nSelf, mergedTopVolBranchLowerEnd, nIncoming);
|
||||
vtkm::cont::Algorithm::CopySubRange<ValueType, ValueType>(
|
||||
inArray, 0, nSelf, mergedTopVolBranchSaddleIsoValue, nIncoming);
|
||||
|
||||
@ -439,17 +439,17 @@ void SelectTopVolumeContoursFunctor::operator()(
|
||||
if (nMergedUnique > this->nSavedBranches)
|
||||
{
|
||||
vtkm::cont::Algorithm::CopySubRange(
|
||||
mergedUniqueBranchGRId, 0, this->nSavedBranches, b->TopVolumeBranchRootGRId);
|
||||
mergedUniqueBranchGRId, 0, this->nSavedBranches, b->tData.TopVolumeBranchRootGRId);
|
||||
vtkm::cont::Algorithm::CopySubRange(
|
||||
mergedUniqueBranchVolume, 0, this->nSavedBranches, b->TopVolumeBranchVolume);
|
||||
mergedUniqueBranchVolume, 0, this->nSavedBranches, b->tData.TopVolumeBranchVolume);
|
||||
vtkm::cont::Algorithm::CopySubRange(mergedUniqueBranchSaddleEpsilon,
|
||||
0,
|
||||
this->nSavedBranches,
|
||||
b->TopVolumeBranchSaddleEpsilon);
|
||||
b->tData.TopVolumeBranchSaddleEpsilon);
|
||||
vtkm::cont::Algorithm::CopySubRange(
|
||||
mergedUniqueBranchUpperEnd, 0, this->nSavedBranches, b->TopVolumeBranchUpperEndGRId);
|
||||
mergedUniqueBranchUpperEnd, 0, this->nSavedBranches, b->tData.TopVolumeBranchUpperEndGRId);
|
||||
vtkm::cont::Algorithm::CopySubRange(
|
||||
mergedUniqueBranchLowerEnd, 0, this->nSavedBranches, b->TopVolumeBranchLowerEndGRId);
|
||||
mergedUniqueBranchLowerEnd, 0, this->nSavedBranches, b->tData.TopVolumeBranchLowerEndGRId);
|
||||
// InArrayHandleType subRangeUniqueBranchSaddleIsoValue;
|
||||
inArray.Allocate(this->nSavedBranches);
|
||||
vtkm::cont::Algorithm::CopySubRange(
|
||||
@ -458,17 +458,17 @@ void SelectTopVolumeContoursFunctor::operator()(
|
||||
}
|
||||
else
|
||||
{
|
||||
vtkm::cont::Algorithm::Copy(mergedUniqueBranchGRId, b->TopVolumeBranchRootGRId);
|
||||
vtkm::cont::Algorithm::Copy(mergedUniqueBranchVolume, b->TopVolumeBranchVolume);
|
||||
vtkm::cont::Algorithm::Copy(mergedUniqueBranchGRId, b->tData.TopVolumeBranchRootGRId);
|
||||
vtkm::cont::Algorithm::Copy(mergedUniqueBranchVolume, b->tData.TopVolumeBranchVolume);
|
||||
vtkm::cont::Algorithm::Copy(mergedUniqueBranchSaddleEpsilon,
|
||||
b->TopVolumeBranchSaddleEpsilon);
|
||||
vtkm::cont::Algorithm::Copy(mergedUniqueBranchUpperEnd, b->TopVolumeBranchUpperEndGRId);
|
||||
vtkm::cont::Algorithm::Copy(mergedUniqueBranchLowerEnd, b->TopVolumeBranchLowerEndGRId);
|
||||
b->tData.TopVolumeBranchSaddleEpsilon);
|
||||
vtkm::cont::Algorithm::Copy(mergedUniqueBranchUpperEnd, b->tData.TopVolumeBranchUpperEndGRId);
|
||||
vtkm::cont::Algorithm::Copy(mergedUniqueBranchLowerEnd, b->tData.TopVolumeBranchLowerEndGRId);
|
||||
inArray.Allocate(nMergedUnique);
|
||||
vtkm::cont::Algorithm::Copy(mergedUniqueBranchSaddleIsoValue, inArray);
|
||||
}
|
||||
};
|
||||
b->TopVolumeBranchSaddleIsoValue
|
||||
b->tData.TopVolumeBranchSaddleIsoValue
|
||||
.CastAndCallForTypes<vtkm::TypeListScalarAll, vtkm::cont::StorageListBasic>(resolveArray);
|
||||
}
|
||||
}
|
||||
|
527
vtkm/filter/scalar_topology/worklet/select_top_volume_contours/BranchDecompositionTreeMaker.h
Normal file
527
vtkm/filter/scalar_topology/worklet/select_top_volume_contours/BranchDecompositionTreeMaker.h
Normal file
@ -0,0 +1,527 @@
|
||||
//============================================================================
|
||||
// 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 (c) 2018, The Regents of the University of California, through
|
||||
// Lawrence Berkeley National Laboratory (subject to receipt of any required approvals
|
||||
// from the U.S. Dept. of Energy). All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// (1) Redistributions of source code must retain the above copyright notice, this
|
||||
// list of conditions and the following disclaimer.
|
||||
//
|
||||
// (2) Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// (3) Neither the name of the University of California, Lawrence Berkeley National
|
||||
// Laboratory, U.S. Dept. of Energy nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without
|
||||
// specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//=======================================================================================
|
||||
//
|
||||
// Parallel Peak Pruning v. 2.0
|
||||
//
|
||||
// Started June 15, 2017
|
||||
//
|
||||
// Copyright Hamish Carr, University of Leeds
|
||||
//
|
||||
// BranchDecompositionTreeMaker.h
|
||||
//
|
||||
//=======================================================================================
|
||||
//
|
||||
// COMMENTS:
|
||||
//
|
||||
// This class computes the branch decomposition tree of top-volume branches
|
||||
//
|
||||
//=======================================================================================
|
||||
|
||||
|
||||
#ifndef vtk_m_filter_scalar_topology_worklet_BranchDecompositionTreeMaker_h
|
||||
#define vtk_m_filter_scalar_topology_worklet_BranchDecompositionTreeMaker_h
|
||||
|
||||
|
||||
#ifdef DEBUG_PRINT
|
||||
#define DEBUG_BRANCH_DECOMPOSITION_TREE_MAKER
|
||||
#endif
|
||||
|
||||
#include <vtkm/cont/ArrayCopy.h>
|
||||
#include <vtkm/filter/scalar_topology/worklet/select_top_volume_contours/TopVolumeBranchData.h>
|
||||
#include <vtkm/filter/scalar_topology/worklet/contourtree_augmented/ArrayTransforms.h>
|
||||
#include <vtkm/filter/scalar_topology/worklet/select_top_volume_contours/BranchParentComparator.h>
|
||||
#include <vtkm/filter/scalar_topology/worklet/select_top_volume_contours/ClarifyBranchEndSupernodeTypeWorklet.h>
|
||||
#include <vtkm/filter/scalar_topology/worklet/select_top_volume_contours/GetBranchHierarchyWorklet.h>
|
||||
#include <vtkm/filter/scalar_topology/worklet/select_top_volume_contours/GetBranchVolumeWorklet.h>
|
||||
#include <vtkm/filter/scalar_topology/worklet/select_top_volume_contours/LocalIsosurfaceExtractWorklet.h>
|
||||
#include <vtkm/filter/scalar_topology/worklet/select_top_volume_contours/Predicates.h>
|
||||
#include <vtkm/filter/scalar_topology/worklet/select_top_volume_contours/UpdateInfoByBranchDirectionWorklet.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace filter
|
||||
{
|
||||
namespace scalar_topology
|
||||
{
|
||||
|
||||
/// Facture class for augmenting the hierarchical contour tree to enable computations of measures, e.g., volumne
|
||||
class BranchDecompositionTreeMaker
|
||||
{ // class BranchDecompositionTreeMaker
|
||||
public:
|
||||
void ComputeTopVolumeBranchHierarchy(const vtkm::cont::DataSet& bdDataSet,
|
||||
TopVolumeBranchData& tData);
|
||||
|
||||
private:
|
||||
/// Used internally to Invoke worklets
|
||||
vtkm::cont::Invoker invoke;
|
||||
|
||||
}; // class BranchDecompositionTreeMaker
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Pipeline to compute the hierarchy of top branches by volume
|
||||
/// </summary>
|
||||
inline void BranchDecompositionTreeMaker::ComputeTopVolumeBranchHierarchy(
|
||||
const vtkm::cont::DataSet& bdDataSet,
|
||||
TopVolumeBranchData& tData)
|
||||
{
|
||||
using vtkm::worklet::contourtree_augmented::IdArrayType;
|
||||
|
||||
// we need upper/lower local ends and global ends for hierarchy of branches
|
||||
auto upperLocalEndIds = bdDataSet.GetField("UpperEndLocalIds")
|
||||
.GetData()
|
||||
.AsArrayHandle<vtkm::cont::ArrayHandle<vtkm::Id>>();
|
||||
auto lowerLocalEndIds = bdDataSet.GetField("LowerEndLocalIds")
|
||||
.GetData()
|
||||
.AsArrayHandle<vtkm::cont::ArrayHandle<vtkm::Id>>();
|
||||
auto globalRegularIds = bdDataSet.GetField("RegularNodeGlobalIds")
|
||||
.GetData()
|
||||
.AsArrayHandle<vtkm::cont::ArrayHandle<vtkm::Id>>();
|
||||
IdArrayType upperEndGRIds =
|
||||
bdDataSet.GetField("UpperEndGlobalRegularIds").GetData().AsArrayHandle<IdArrayType>();
|
||||
IdArrayType lowerEndGRIds =
|
||||
bdDataSet.GetField("LowerEndGlobalRegularIds").GetData().AsArrayHandle<IdArrayType>();
|
||||
|
||||
// let's check which top volume branches are known by the block
|
||||
// We check the branchGRId of top volume branches to see whether there are matches within the block
|
||||
const vtkm::Id nTopVolBranches = tData.TopVolumeBranchLowerEndGRId.GetNumberOfValues();
|
||||
|
||||
// sortedBranchOrder: the branch order (in the ascending order of branch root)
|
||||
// the high-level idea is to sort the branch root global regular ids
|
||||
// and for each top-volume branch, we use binary search to get the original branch index
|
||||
// if the top-volume branch does not exist in the block, it will be dropped out
|
||||
IdArrayType sortedBranchGRId;
|
||||
IdArrayType sortedBranchOrder;
|
||||
vtkm::cont::Algorithm::Copy(
|
||||
vtkm::cont::ArrayHandleIndex(tData.BranchRootGRId.GetNumberOfValues()), sortedBranchOrder);
|
||||
vtkm::cont::Algorithm::Copy(tData.BranchRootGRId, sortedBranchGRId);
|
||||
vtkm::cont::Algorithm::SortByKey(sortedBranchGRId, sortedBranchOrder);
|
||||
|
||||
tData.TopVolBranchKnownByBlockStencil.Allocate(nTopVolBranches);
|
||||
tData.TopVolBranchGROrder.Allocate(nTopVolBranches);
|
||||
|
||||
// We reuse the IdxIfWithinBlockWorklet.
|
||||
// This worklet searches for given values in a sorted array and returns the stencil & index if the value exists in the array.
|
||||
// tData.TopVolBranchGROrder: the order of the topVolBranch among all known branches if the branch is known by the block.
|
||||
auto idxIfBranchWithinBlockWorklet =
|
||||
vtkm::worklet::scalar_topology::select_top_volume_contours::IdxIfWithinBlockWorklet();
|
||||
invoke(idxIfBranchWithinBlockWorklet,
|
||||
tData.TopVolumeBranchRootGRId,
|
||||
sortedBranchGRId,
|
||||
tData.TopVolBranchKnownByBlockStencil,
|
||||
tData.TopVolBranchGROrder);
|
||||
|
||||
// Dropping out top-volume branches that are not known by the block.
|
||||
|
||||
// the index of top-volume branches known by the block among all top-volume branches
|
||||
IdArrayType topVolBranchKnownByBlockIndex;
|
||||
vtkm::cont::ArrayHandleIndex topVolBranchesIndex(nTopVolBranches);
|
||||
vtkm::cont::Algorithm::CopyIf(
|
||||
topVolBranchesIndex, tData.TopVolBranchKnownByBlockStencil, topVolBranchKnownByBlockIndex);
|
||||
|
||||
const vtkm::Id nTopVolBranchKnownByBlock = topVolBranchKnownByBlockIndex.GetNumberOfValues();
|
||||
|
||||
// filtered tData.TopVolBranchGROrder, by removing NO_SUCH_ELEMENT
|
||||
IdArrayType topVolBranchFilteredGROrder;
|
||||
|
||||
// tData.TopVolBranchInfoActualIndex: the information index of the top-volume branch
|
||||
vtkm::cont::Algorithm::CopyIf(
|
||||
tData.TopVolBranchGROrder, tData.TopVolBranchKnownByBlockStencil, topVolBranchFilteredGROrder);
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
sortedBranchOrder, topVolBranchFilteredGROrder, tData.TopVolBranchInfoActualIndex);
|
||||
|
||||
// filtered branch saddle epsilons, global lower/upper end GR ids,
|
||||
IdArrayType topVolFilteredBranchSaddleEpsilon;
|
||||
IdArrayType topVolFilteredLowerEndGRId;
|
||||
IdArrayType topVolFilteredUpperEndGRId;
|
||||
vtkm::cont::Algorithm::CopyIf(tData.TopVolumeBranchSaddleEpsilon,
|
||||
tData.TopVolBranchKnownByBlockStencil,
|
||||
topVolFilteredBranchSaddleEpsilon);
|
||||
vtkm::cont::Algorithm::CopyIf(tData.TopVolumeBranchUpperEndGRId,
|
||||
tData.TopVolBranchKnownByBlockStencil,
|
||||
topVolFilteredUpperEndGRId);
|
||||
vtkm::cont::Algorithm::CopyIf(tData.TopVolumeBranchLowerEndGRId,
|
||||
tData.TopVolBranchKnownByBlockStencil,
|
||||
topVolFilteredLowerEndGRId);
|
||||
|
||||
// for each top-vol branch known by the block
|
||||
// we get their upper end and lower end local ids
|
||||
IdArrayType topVolBranchUpperLocalEnd;
|
||||
IdArrayType topVolBranchLowerLocalEnd;
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
upperLocalEndIds, tData.TopVolBranchInfoActualIndex, topVolBranchUpperLocalEnd);
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
lowerLocalEndIds, tData.TopVolBranchInfoActualIndex, topVolBranchLowerLocalEnd);
|
||||
|
||||
IdArrayType topVolLowerLocalEndGRId;
|
||||
IdArrayType topVolUpperLocalEndGRId;
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
globalRegularIds, topVolBranchLowerLocalEnd, topVolLowerLocalEndGRId);
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
globalRegularIds, topVolBranchUpperLocalEnd, topVolUpperLocalEndGRId);
|
||||
|
||||
// Below is the code to compute the branch hierarchy of top-volume branches
|
||||
// We need this information because we not only want to visualize the contour
|
||||
// on top-volume branches, but also on their parent branches.
|
||||
// Because we use volume as the metric, the parent branch of a top-volume branch
|
||||
// is either a top-volume branch or the root branch (where both ends are leaf nodes)
|
||||
vtkm::worklet::scalar_topology::select_top_volume_contours::BranchSaddleIsKnownWorklet
|
||||
branchSaddleIsKnownWorklet;
|
||||
// the branch saddle local ID if the saddle end is known by the block
|
||||
IdArrayType branchSaddleIsKnown;
|
||||
branchSaddleIsKnown.Allocate(nTopVolBranchKnownByBlock);
|
||||
|
||||
invoke(branchSaddleIsKnownWorklet, // worklet
|
||||
topVolFilteredLowerEndGRId, // input
|
||||
topVolBranchLowerLocalEnd, // input
|
||||
topVolLowerLocalEndGRId, // input
|
||||
topVolFilteredUpperEndGRId, // input
|
||||
topVolBranchUpperLocalEnd, // input
|
||||
topVolUpperLocalEndGRId, // input
|
||||
topVolFilteredBranchSaddleEpsilon, // input
|
||||
branchSaddleIsKnown); // output
|
||||
|
||||
// the order of top volume branches with parents known by the block
|
||||
IdArrayType topVolChildBranch;
|
||||
IdArrayType topVolChildBranchSaddle;
|
||||
|
||||
vtkm::cont::Algorithm::CopyIf(
|
||||
topVolBranchKnownByBlockIndex,
|
||||
branchSaddleIsKnown,
|
||||
topVolChildBranch,
|
||||
vtkm::worklet::scalar_topology::select_top_volume_contours::IsNonNegative());
|
||||
vtkm::cont::Algorithm::CopyIf(
|
||||
branchSaddleIsKnown,
|
||||
branchSaddleIsKnown,
|
||||
topVolChildBranchSaddle,
|
||||
vtkm::worklet::scalar_topology::select_top_volume_contours::IsNonNegative());
|
||||
|
||||
const vtkm::Id nChildBranch = topVolChildBranch.GetNumberOfValues();
|
||||
|
||||
// to compute the parent branch, we need to
|
||||
// 1. for the branch saddle end, collect all superarcs involving it
|
||||
// 2. get the branch information for selected superarcs
|
||||
// 3. eliminate branch information for branches sharing the same saddle end
|
||||
|
||||
auto superarcs =
|
||||
bdDataSet.GetField("Superarcs").GetData().AsArrayHandle<vtkm::cont::ArrayHandle<vtkm::Id>>();
|
||||
auto branchRoots =
|
||||
bdDataSet.GetField("BranchRoots").GetData().AsArrayHandle<vtkm::cont::ArrayHandle<vtkm::Id>>();
|
||||
VTKM_ASSERT(superarcs.GetNumberOfValues() == branchRoots.GetNumberOfValues());
|
||||
|
||||
// we sort all superarcs by target to allow binary search
|
||||
IdArrayType superarcsByTarget;
|
||||
vtkm::worklet::scalar_topology::select_top_volume_contours::SuperarcTargetComparator
|
||||
superarcComparator(superarcs);
|
||||
vtkm::cont::Algorithm::Copy(vtkm::cont::ArrayHandleIndex(superarcs.GetNumberOfValues()),
|
||||
superarcsByTarget);
|
||||
vtkm::cont::Algorithm::Sort(superarcsByTarget, superarcComparator);
|
||||
|
||||
IdArrayType permutedSuperarcs;
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
superarcs, superarcsByTarget, permutedSuperarcs);
|
||||
|
||||
IdArrayType permutedBranchRoots;
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
branchRoots, superarcsByTarget, permutedBranchRoots);
|
||||
|
||||
// the branch root of the superarc of the branch saddle supernode
|
||||
IdArrayType topVolChildBranchSaddleBranchRoot;
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
branchRoots, topVolChildBranchSaddle, topVolChildBranchSaddleBranchRoot);
|
||||
|
||||
// the GR Ids of the superarc of the branch saddle supernode
|
||||
IdArrayType topVolChildBranchSaddleGRIds;
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
globalRegularIds, topVolChildBranchSaddle, topVolChildBranchSaddleGRIds);
|
||||
|
||||
// there is a debate to find all superarcs connect to a supernode
|
||||
// strategy 1. iterate through saddles and parallelize over superarcs for search
|
||||
// time complexity: O(nTopVolBranches)
|
||||
// (nTopVolBranches usually <= 100, based on input parameter setting)
|
||||
//
|
||||
// strategy 2. parallelize over all saddles and use binary search to find superarcs
|
||||
// time complexity: O(log_2(nSuperarcs)) (nSuperarcs can be considerably large)
|
||||
//
|
||||
// here, we choose strategy 2 for better extendability to high nTopVolBranches
|
||||
// but in tests using nTopVolBranches <= 10, strategy 1 is generally faster
|
||||
|
||||
// note: after getting the branch root superarc, we use binary search to get the branch order
|
||||
// because BranchRootByBranch is sorted by branch root (superarc) id
|
||||
|
||||
#ifdef DEBUG_PRINT
|
||||
std::stringstream parentBranchStream;
|
||||
vtkm::worklet::contourtree_augmented::PrintHeader(nChildBranch, parentBranchStream);
|
||||
vtkm::worklet::contourtree_augmented::PrintIndices(
|
||||
"Child Branch Saddle", topVolChildBranchSaddle, -1, parentBranchStream);
|
||||
vtkm::worklet::contourtree_augmented::PrintIndices(
|
||||
"Child Saddle Root", topVolChildBranchSaddleBranchRoot, -1, parentBranchStream);
|
||||
vtkm::worklet::contourtree_augmented::PrintIndices(
|
||||
"Child Saddle GR Id", topVolChildBranchSaddleGRIds, -1, parentBranchStream);
|
||||
|
||||
vtkm::worklet::contourtree_augmented::PrintHeader(superarcs.GetNumberOfValues(),
|
||||
parentBranchStream);
|
||||
vtkm::worklet::contourtree_augmented::PrintIndices(
|
||||
"Permuted Superarcs", permutedSuperarcs, -1, parentBranchStream);
|
||||
vtkm::worklet::contourtree_augmented::PrintIndices(
|
||||
"Permuted Branch roots", permutedBranchRoots, -1, parentBranchStream);
|
||||
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Info, parentBranchStream.str());
|
||||
#endif // DEBUG_PRINT
|
||||
|
||||
// the corresponding parent branch of child branches
|
||||
IdArrayType topVolChildBranchParent;
|
||||
topVolChildBranchParent.AllocateAndFill(nChildBranch,
|
||||
vtkm::worklet::contourtree_augmented::NO_SUCH_ELEMENT);
|
||||
vtkm::worklet::scalar_topology::select_top_volume_contours::GetParentBranchWorklet
|
||||
getParentBranchWorklet;
|
||||
invoke(getParentBranchWorklet,
|
||||
topVolChildBranchSaddle,
|
||||
topVolChildBranchSaddleBranchRoot,
|
||||
topVolChildBranchSaddleGRIds,
|
||||
permutedSuperarcs,
|
||||
permutedBranchRoots,
|
||||
tData.BranchRootByBranch,
|
||||
upperEndGRIds,
|
||||
lowerEndGRIds,
|
||||
topVolChildBranchParent);
|
||||
|
||||
tData.TopVolumeBranchParent.AllocateAndFill(
|
||||
nTopVolBranches, vtkm::Id(vtkm::worklet::contourtree_augmented::NO_SUCH_ELEMENT));
|
||||
|
||||
vtkm::worklet::scalar_topology::select_top_volume_contours::AssignValueByIndex assignParentBranch;
|
||||
// for each top volume branch, assign the parent branch info id in the block
|
||||
invoke(
|
||||
assignParentBranch, topVolChildBranch, topVolChildBranchParent, tData.TopVolumeBranchParent);
|
||||
// for each branch, assign true if it is a parent branch
|
||||
invoke(assignParentBranch,
|
||||
topVolChildBranchParent,
|
||||
vtkm::cont::ArrayHandleConstant<bool>(true, nChildBranch),
|
||||
tData.IsParentBranch);
|
||||
|
||||
// sort all top-volume branches based on
|
||||
// 1. parent branch info id: tData.TopVolumeBranchParent
|
||||
// 2. saddle-end value: tData.TopVolumeBranchSaddleIsovalue
|
||||
// 3. branch root global regular id (anything that can break tie)
|
||||
IdArrayType topVolSortForOuterSaddleIdx;
|
||||
vtkm::cont::Algorithm::Copy(topVolBranchesIndex, topVolSortForOuterSaddleIdx);
|
||||
|
||||
auto resolveBranchParentSorter = [&](const auto& inArray)
|
||||
{
|
||||
using InArrayHandleType = std::decay_t<decltype(inArray)>;
|
||||
using ValueType = typename InArrayHandleType::ValueType;
|
||||
|
||||
vtkm::worklet::scalar_topology::select_top_volume_contours::BranchParentComparator<ValueType>
|
||||
parentComparator(tData.TopVolumeBranchParent, inArray, tData.TopVolumeBranchRootGRId);
|
||||
|
||||
// sort index for all top volume branches
|
||||
vtkm::cont::Algorithm::Sort(topVolSortForOuterSaddleIdx, parentComparator);
|
||||
};
|
||||
tData.TopVolumeBranchSaddleIsoValue
|
||||
.CastAndCallForTypes<vtkm::TypeListScalarAll, vtkm::cont::StorageListBasic>(
|
||||
resolveBranchParentSorter);
|
||||
|
||||
IdArrayType parentPermutation;
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
tData.TopVolumeBranchParent, topVolSortForOuterSaddleIdx, parentPermutation);
|
||||
|
||||
// warning: when parent is NO_SUCH_ELEMENT, parentSaddleEps obtains 0
|
||||
// However, the corresponding element will be discarded in collecting outer saddles
|
||||
IdArrayType parentSaddleEpsPermutation;
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
tData.BranchSaddleEpsilon, parentPermutation, parentSaddleEpsPermutation);
|
||||
|
||||
// Some branches have parent=NO_SUCH_ELEMENT (no parent)
|
||||
// we collect the isovalue of the first and/or the last branches for each parent branch
|
||||
// we collect the first if branchSaddleEpsilon(parent) < 0
|
||||
// or the last if branchSaddleEpsilon(parent) > 0
|
||||
// or both if branchSaddleEpsilon(parent) == 0
|
||||
IdArrayType IsOuterSaddle;
|
||||
IsOuterSaddle.Allocate(nTopVolBranches);
|
||||
vtkm::worklet::scalar_topology::select_top_volume_contours::CollectOuterSaddle
|
||||
collectOuterSaddleWorklet;
|
||||
invoke(collectOuterSaddleWorklet, parentSaddleEpsPermutation, parentPermutation, IsOuterSaddle);
|
||||
|
||||
// after sorting by index back
|
||||
// each top volume branch know whether it is the outer saddle of its parent
|
||||
vtkm::cont::Algorithm::SortByKey(topVolSortForOuterSaddleIdx, IsOuterSaddle);
|
||||
|
||||
// collect branches that need contours on extra minima/maxima
|
||||
// we store the information of the parent branches (on both directions)
|
||||
IdArrayType extraMaximaParentBranch;
|
||||
IdArrayType extraMinimaParentBranch;
|
||||
IdArrayType extraMaximaParentBranchRootGRId;
|
||||
IdArrayType extraMinimaParentBranchRootGRId;
|
||||
|
||||
IdArrayType allBranchGRIdByVolume;
|
||||
IdArrayType branchGRIdByVolumeIdx;
|
||||
|
||||
// we need global branch order including the root branch
|
||||
// this information should be consistent globally
|
||||
allBranchGRIdByVolume.Allocate(nTopVolBranches + 1);
|
||||
vtkm::cont::Algorithm::CopySubRange(
|
||||
tData.TopVolumeBranchRootGRId, 0, nTopVolBranches, allBranchGRIdByVolume, 1);
|
||||
auto topBranchGRIdWritePortal = allBranchGRIdByVolume.WritePortal();
|
||||
auto sortedBranchByVolPortal = tData.SortedBranchByVolume.ReadPortal();
|
||||
auto branchGRIdReadPortal = tData.BranchRootGRId.ReadPortal();
|
||||
topBranchGRIdWritePortal.Set(0, branchGRIdReadPortal.Get(sortedBranchByVolPortal.Get(0)));
|
||||
|
||||
vtkm::cont::Algorithm::Copy(
|
||||
vtkm::cont::ArrayHandleIndex(allBranchGRIdByVolume.GetNumberOfValues()),
|
||||
branchGRIdByVolumeIdx);
|
||||
vtkm::cont::Algorithm::SortByKey(allBranchGRIdByVolume, branchGRIdByVolumeIdx);
|
||||
|
||||
vtkm::cont::Algorithm::CopyIf(
|
||||
tData.TopVolumeBranchParent,
|
||||
IsOuterSaddle,
|
||||
extraMaximaParentBranch,
|
||||
vtkm::worklet::scalar_topology::select_top_volume_contours::IsExtraMaxima());
|
||||
vtkm::cont::Algorithm::CopyIf(
|
||||
tData.TopVolumeBranchParent,
|
||||
IsOuterSaddle,
|
||||
extraMinimaParentBranch,
|
||||
vtkm::worklet::scalar_topology::select_top_volume_contours::IsExtraMinima());
|
||||
|
||||
if (extraMaximaParentBranch.GetNumberOfValues())
|
||||
{
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
upperLocalEndIds, extraMaximaParentBranch, tData.ExtraMaximaBranchUpperEnd);
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
lowerLocalEndIds, extraMaximaParentBranch, tData.ExtraMaximaBranchLowerEnd);
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
tData.BranchRootGRId, extraMaximaParentBranch, extraMaximaParentBranchRootGRId);
|
||||
|
||||
//InArrayHandleType extraMaximaBranchIsoValue;
|
||||
//vtkm::cont::Algorithm::CopyIf(
|
||||
// tData.TopVolumeBranchSaddleIsoValue.AsArrayHandle<InArrayHandleType>(),
|
||||
// IsOuterSaddle,
|
||||
// extraMaximaBranchIsoValue,
|
||||
// vtkm::worklet::scalar_topology::select_top_volume_contours::IsExtraMaxima());
|
||||
//tData.ExtraMaximaBranchIsoValue = extraMaximaBranchIsoValue;
|
||||
|
||||
// a worklet to binary search a number in a sorted array and return the index
|
||||
vtkm::worklet::scalar_topology::select_top_volume_contours::IdxIfWithinBlockWorklet
|
||||
getParentBranchOrder;
|
||||
IdArrayType permutedExtraMaximaBranchOrder;
|
||||
permutedExtraMaximaBranchOrder.Allocate(extraMaximaParentBranchRootGRId.GetNumberOfValues());
|
||||
vtkm::cont::ArrayHandleDiscard<vtkm::Id> discard;
|
||||
discard.Allocate(extraMaximaParentBranchRootGRId.GetNumberOfValues());
|
||||
invoke(getParentBranchOrder,
|
||||
extraMaximaParentBranchRootGRId,
|
||||
allBranchGRIdByVolume,
|
||||
discard,
|
||||
permutedExtraMaximaBranchOrder);
|
||||
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
branchGRIdByVolumeIdx, permutedExtraMaximaBranchOrder, tData.ExtraMaximaBranchOrder);
|
||||
}
|
||||
|
||||
if (extraMinimaParentBranch.GetNumberOfValues())
|
||||
{
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
upperLocalEndIds, extraMinimaParentBranch, tData.ExtraMinimaBranchUpperEnd);
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
lowerLocalEndIds, extraMinimaParentBranch, tData.ExtraMinimaBranchLowerEnd);
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
tData.BranchRootGRId, extraMinimaParentBranch, extraMinimaParentBranchRootGRId);
|
||||
|
||||
//InArrayHandleType extraMinimaBranchIsoValue;
|
||||
//vtkm::cont::Algorithm::CopyIf(
|
||||
// tData.TopVolumeBranchSaddleIsoValue.AsArrayHandle<InArrayHandleType>(),
|
||||
// IsOuterSaddle,
|
||||
// extraMinimaBranchIsoValue,
|
||||
// vtkm::worklet::scalar_topology::select_top_volume_contours::IsExtraMinima());
|
||||
//tData.ExtraMinimaBranchIsoValue = extraMinimaBranchIsoValue;
|
||||
|
||||
vtkm::worklet::scalar_topology::select_top_volume_contours::IdxIfWithinBlockWorklet
|
||||
getParentBranchOrder;
|
||||
IdArrayType permutedExtraMinimaBranchOrder;
|
||||
permutedExtraMinimaBranchOrder.Allocate(extraMinimaParentBranchRootGRId.GetNumberOfValues());
|
||||
vtkm::cont::ArrayHandleDiscard<vtkm::Id> discard;
|
||||
discard.Allocate(extraMinimaParentBranchRootGRId.GetNumberOfValues());
|
||||
invoke(getParentBranchOrder,
|
||||
extraMinimaParentBranchRootGRId,
|
||||
allBranchGRIdByVolume,
|
||||
discard,
|
||||
permutedExtraMinimaBranchOrder);
|
||||
|
||||
vtkm::worklet::contourtree_augmented::PermuteArrayWithMaskedIndex<vtkm::Id, IdArrayType>(
|
||||
branchGRIdByVolumeIdx, permutedExtraMinimaBranchOrder, tData.ExtraMinimaBranchOrder);
|
||||
}
|
||||
|
||||
auto resolveExtraContourSaddleValue = [&](const auto& inArray)
|
||||
{
|
||||
using InArrayHandleType = std::decay_t<decltype(inArray)>;
|
||||
using ValueType = typename InArrayHandleType::ValueType;
|
||||
|
||||
if (extraMaximaParentBranch.GetNumberOfValues())
|
||||
{
|
||||
InArrayHandleType extraMaximaBranchIsoValue;
|
||||
vtkm::cont::Algorithm::CopyIf(
|
||||
inArray,
|
||||
IsOuterSaddle,
|
||||
extraMaximaBranchIsoValue,
|
||||
vtkm::worklet::scalar_topology::select_top_volume_contours::IsExtraMaxima());
|
||||
tData.ExtraMaximaBranchIsoValue = extraMaximaBranchIsoValue;
|
||||
}
|
||||
|
||||
if (extraMinimaParentBranch.GetNumberOfValues())
|
||||
{
|
||||
InArrayHandleType extraMinimaBranchIsoValue;
|
||||
vtkm::cont::Algorithm::CopyIf(
|
||||
inArray,
|
||||
IsOuterSaddle,
|
||||
extraMinimaBranchIsoValue,
|
||||
vtkm::worklet::scalar_topology::select_top_volume_contours::IsExtraMinima());
|
||||
tData.ExtraMinimaBranchIsoValue = extraMinimaBranchIsoValue;
|
||||
}
|
||||
};
|
||||
tData.TopVolumeBranchSaddleIsoValue
|
||||
.CastAndCallForTypes<vtkm::TypeListScalarAll, vtkm::cont::StorageListBasic>(
|
||||
resolveExtraContourSaddleValue);
|
||||
}
|
||||
|
||||
|
||||
} // namespace scalar_topology
|
||||
} // namespace filter
|
||||
} // namespace vtkm
|
||||
|
||||
#endif
|
@ -10,6 +10,7 @@
|
||||
|
||||
set(headers
|
||||
Predicates.h
|
||||
TopVolumeBranchData.h
|
||||
ClarifyBranchEndSupernodeTypeWorklet.h
|
||||
UpdateInfoByBranchDirectionWorklet.h
|
||||
GetBranchHierarchyWorklet.h
|
||||
@ -18,6 +19,7 @@ set(headers
|
||||
BranchVolumeComparator.h
|
||||
MarchingCubesDataTables.h
|
||||
LocalIsosurfaceExtractWorklet.h
|
||||
BranchDecompositionTreeMaker.h
|
||||
)
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
|
131
vtkm/filter/scalar_topology/worklet/select_top_volume_contours/TopVolumeBranchData.h
Normal file
131
vtkm/filter/scalar_topology/worklet/select_top_volume_contours/TopVolumeBranchData.h
Normal file
@ -0,0 +1,131 @@
|
||||
//============================================================================
|
||||
// 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 (c) 2018, The Regents of the University of California, through
|
||||
// Lawrence Berkeley National Laboratory (subject to receipt of any required approvals
|
||||
// from the U.S. Dept. of Energy). All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// (1) Redistributions of source code must retain the above copyright notice, this
|
||||
// list of conditions and the following disclaimer.
|
||||
//
|
||||
// (2) Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// (3) Neither the name of the University of California, Lawrence Berkeley National
|
||||
// Laboratory, U.S. Dept. of Energy nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without
|
||||
// specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//=======================================================================================
|
||||
//
|
||||
// Parallel Peak Pruning v. 2.0
|
||||
//
|
||||
// Started June 15, 2017
|
||||
//
|
||||
// Copyright Hamish Carr, University of Leeds
|
||||
//
|
||||
// BranchDecompositionTreeMaker.h
|
||||
//
|
||||
//=======================================================================================
|
||||
//
|
||||
// COMMENTS:
|
||||
//
|
||||
// This class computes the branch decomposition tree of top-volume branches
|
||||
//
|
||||
//=======================================================================================
|
||||
|
||||
|
||||
#ifndef vtk_m_filter_scalar_topology_worklet_TopVolumeBranchData_h
|
||||
#define vtk_m_filter_scalar_topology_worklet_TopVolumeBranchData_h
|
||||
|
||||
#include <vtkm/filter/scalar_topology/worklet/contourtree_augmented/Types.h>
|
||||
|
||||
#ifdef DEBUG_PRINT
|
||||
#define DEBUG_BRANCH_DECOMPOSITION_TREE_MAKER
|
||||
#endif
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace filter
|
||||
{
|
||||
namespace scalar_topology
|
||||
{
|
||||
|
||||
/// Data to store all information about top branches by volume
|
||||
struct TopVolumeBranchData
|
||||
{ // struct TopVolumeBranchData
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType BranchRootByBranch;
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType BranchRootGRId;
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType BranchVolume;
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType BranchSaddleEpsilon;
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType SortedBranchByVolume;
|
||||
vtkm::cont::ArrayHandle<bool> IsParentBranch;
|
||||
vtkm::cont::UnknownArrayHandle BranchSaddleIsoValue;
|
||||
|
||||
// Output Datasets.
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType TopVolumeBranchRoot;
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType TopVolumeBranchRootGRId;
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType TopVolumeBranchVolume;
|
||||
// the parent branch of top volume branches (if no parent branch, then NO_SUCH_ELEMENT)
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType TopVolumeBranchParent;
|
||||
vtkm::cont::UnknownArrayHandle TopVolumeBranchSaddleIsoValue;
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType TopVolumeBranchSaddleEpsilon;
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType TopVolumeBranchUpperEndGRId;
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType TopVolumeBranchLowerEndGRId;
|
||||
|
||||
// Other top-volume branch information
|
||||
|
||||
// whether the top volume branch is known by the block
|
||||
// size: nTopVolBranches
|
||||
// value range: [0, 1]
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType TopVolBranchKnownByBlockStencil;
|
||||
// the branch order (among all branches) by branch root global regular ids
|
||||
// size: nTopVolBranches
|
||||
// value range: {NO_SUCH_ELEMENT} U [0, nBranches - 1]
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType TopVolBranchGROrder;
|
||||
// the branch information index (known by the block) of the top volume branch
|
||||
// size: nTopVolBranchKnownByBlock
|
||||
// value range: [0, nBranches - 1]
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType TopVolBranchInfoActualIndex;
|
||||
|
||||
// information to extract extra isosurface for extrema
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType ExtraMaximaBranchUpperEnd;
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType ExtraMaximaBranchLowerEnd;
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType ExtraMaximaBranchOrder;
|
||||
vtkm::cont::UnknownArrayHandle ExtraMaximaBranchIsoValue;
|
||||
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType ExtraMinimaBranchUpperEnd;
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType ExtraMinimaBranchLowerEnd;
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType ExtraMinimaBranchOrder;
|
||||
vtkm::cont::UnknownArrayHandle ExtraMinimaBranchIsoValue;
|
||||
}; // class TopVolumeBranchData
|
||||
|
||||
|
||||
|
||||
} // namespace scalar_topology
|
||||
} // namespace filter
|
||||
} // namespace vtkm
|
||||
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user