review(CompositeArr): allow for nullptr in backend construction

Also:
- improve documentation
HTGFixUnlimitedToRoot
Julien Fausty 2022-11-23 12:01:12 +01:00
parent 86a5ba59e2
commit 121f39a8da
6 changed files with 53 additions and 7 deletions

View File

@ -143,5 +143,19 @@ int TestCompositeArray(int vtkNotUsed(argc), char* vtkNotUsed(argv)[])
iArr++;
}
#endif // VTK_DISPATCH_COMPOSITE_ARRAYS
// test a 1 composite
vtkSmartPointer<vtkCompositeArray<int>> oneComposite =
vtk::ConcatenateDataArrays<int>(std::vector<vtkDataArray*>({ composite }));
for (iArr = 0; iArr < 100; iArr++)
{
if (oneComposite->GetValue(iArr) != iArr)
{
res = EXIT_FAILURE;
std::cout << "get value failed with vtkCompositeArray for composite with one array: " << iArr
<< " != " << composite->GetValue(iArr) << std::endl;
}
}
return res;
};

View File

@ -50,6 +50,8 @@
* rightArr->SetValue(0, 1);
* vtkNew<vtkCompositeArray<int>> compositeArr;
* compositeArr->SetBackend(std::make_shared<vtkCompositeImplicitBackend<int>>(leftArr, rightArr));
* compositeArr->SetNumberOfComponents(1);
* compositeArr->SetNumberOfTuples(2);
* CHECK(compositArr->GetValue(1) == 1);
* ```
* @sa
@ -66,6 +68,14 @@ namespace vtk
{
VTK_ABI_NAMESPACE_BEGIN
template <typename T>
/**
* \fn ConcatenateDataArrays
* A method that can take a `std::vector` of `vtkDataArray`s and concatenate them together into a
* single `vtkCompositeArray`. Input arrays should all have the same number of components and the
* resulting composite array has as many tuples as the sum of all the inputs.
*
* The method is templated based on the value type of composite array the caller wishes as a result.
*/
vtkSmartPointer<vtkCompositeArray<T>> ConcatenateDataArrays(
const std::vector<vtkDataArray*>& arrays);
VTK_ABI_NAMESPACE_END

View File

@ -10,10 +10,18 @@ template <typename T>
vtkSmartPointer<vtkCompositeArray<T>> ConcatenateDataArrays(
const std::vector<vtkDataArray*>& arrays)
{
if (arrays.size() < 2)
if (arrays.size() == 0)
{
return nullptr;
}
if (arrays.size() == 1)
{
vtkNew<vtkCompositeArray<T>> composite;
composite->SetBackend(std::make_shared<vtkCompositeImplicitBackend<T>>(arrays[0], nullptr));
composite->SetNumberOfComponents(arrays[0]->GetNumberOfComponents());
composite->SetNumberOfTuples(arrays[0]->GetNumberOfTuples());
return composite;
}
vtkIdType nComps = arrays[0]->GetNumberOfComponents();
for (auto arr : arrays)
{

View File

@ -42,6 +42,10 @@
* compositeArr->SetBackend(std::make_shared<vtkCompositeImplicitBackend<int>>(leftArr, rightArr));
* CHECK(compositArr->GetValue(1) == 1);
* ```
*
* > WARNING:
* > Arrays input to the backend are flattened upon use and are no longer sensitive to component
* > information.
*/
#include "vtkCommonImplicitArraysModule.h"
#include <memory>

View File

@ -14,6 +14,7 @@
=========================================================================*/
#include "vtkCompositeImplicitBackend.h"
#include "vtkAOSDataArrayTemplate.h"
#include "vtkArrayDispatch.h"
#include "vtkArrayDispatchImplicitArrayList.h"
#include "vtkDataArray.h"
@ -29,19 +30,28 @@ struct vtkCompositeImplicitBackend<ValueType>::Internals
: Left(leftArr)
, Right(rightArr)
{
if (this->Left == nullptr || this->Right == nullptr)
if (!this->Left && !this->Right)
{
vtkErrorWithObjectMacro(nullptr, "Creating composite array with nullptr");
return;
vtkWarningWithObjectMacro(nullptr, "Creating composite array with two nullptrs");
}
auto checkNullRectify = [](vtkSmartPointer<vtkDataArray>& arr) {
if (!arr)
{
arr = vtkSmartPointer<vtkAOSDataArrayTemplate<ValueType>>::New();
arr->SetNumberOfComponents(1);
arr->SetNumberOfTuples(0);
}
};
checkNullRectify(this->Left);
checkNullRectify(this->Right);
this->LeftRange = vtk::DataArrayValueRange(this->Left);
this->RightRange = vtk::DataArrayValueRange(this->Right);
this->Offset = this->LeftRange.size();
}
const vtkSmartPointer<vtkDataArray> Left;
vtkSmartPointer<vtkDataArray> Left;
vtk::detail::SelectValueRange<vtkDataArray*, vtk::detail::DynamicTupleSize>::type LeftRange;
const vtkSmartPointer<vtkDataArray> Right;
vtkSmartPointer<vtkDataArray> Right;
vtk::detail::SelectValueRange<vtkDataArray*, vtk::detail::DynamicTupleSize>::type RightRange;
int Offset = -1;
};

View File

@ -22,5 +22,5 @@ CHECK(composite->GetComponent(42, 1) == 0.0); // always true
> **WARNINGS**
>
> * Any two arrays composited into a `vtkCompositeArray` must have the same number of components.
> * Any two arrays composited into a `vtkCompositeArray` using the `vtk::ConcatenateDataArrays` method must have the same number of components.
> * Iteration over the composited array incurs a lot of overhead compared to an explicit memory array (~3x slower with only 1 level). The use case is truly when memory efficiency is more important than compute performance.