Commit 3cdb6ad7 authored by Savici, Andrei T's avatar Savici, Andrei T
Browse files

Merge pull request #15522 from mantidproject/faster_vtkMDHexFactory

Use direct array access to manipulate vtkUnstructuredGrid
parents 6b8d7701 f0ae3d76
......@@ -4,6 +4,7 @@
#include "MantidAPI/IMDNode.h"
#include "MantidAPI/IMDWorkspace.h"
#include "MantidKernel/CPUTimer.h"
#include "MantidKernel/make_unique.h"
#include "MantidDataObjects/MDEventFactory.h"
#include "MantidVatesAPI/Common.h"
#include "MantidVatesAPI/ProgressAction.h"
......@@ -11,11 +12,14 @@
#include <vtkCellData.h>
#include <vtkFloatArray.h>
#include <vtkHexahedron.h>
#include <vtkNew.h>
#include <vtkPoints.h>
#include <vtkUnstructuredGrid.h>
#include "MantidKernel/ReadLock.h"
#include "MantidKernel/make_unique.h"
#include <iterator>
using namespace Mantid::API;
using namespace Mantid::DataObjects;
using namespace Mantid::Geometry;
......@@ -77,14 +81,14 @@ void vtkMDHexFactory::doCreate(
// Create 8 points per box.
vtkNew<vtkPoints> points;
points->Allocate(numBoxes * 8);
points->SetNumberOfPoints(numBoxes * 8);
vtkFloatArray *pointsArray = vtkFloatArray::SafeDownCast(points->GetData());
float *pointsPtr = pointsArray->WritePointer(0, numBoxes * 8 * 3);
// One scalar per box
vtkNew<vtkFloatArray> signals;
signals->Allocate(numBoxes);
signals->SetName(ScalarName.c_str());
signals->SetNumberOfComponents(1);
float *signalsPtr = signals->WritePointer(0, numBoxes);
// To cache the signal
std::vector<float> signalCache(numBoxes, 0);
......@@ -102,6 +106,7 @@ void vtkMDHexFactory::doCreate(
vtkNew<vtkIdList> hexPointList;
hexPointList->SetNumberOfIds(8);
auto hexPointList_ptr = hexPointList->WritePointer(0, 8);
NormFuncIMDNodePtr normFunction =
makeMDEventNormalizationFunction(m_normalizationOption, ws.get());
......@@ -111,38 +116,31 @@ void vtkMDHexFactory::doCreate(
PRAGMA_OMP( parallel for schedule (dynamic) )
for (int ii = 0; ii < int(boxes.size()); ii++) {
// Get the box here
size_t i = size_t(ii);
size_t i = static_cast<size_t>(ii);
API::IMDNode *box = boxes[i];
Mantid::signal_t signal_normalized = (box->*normFunction)();
if (!isSpecial(signal_normalized) &&
m_thresholdRange->inRange(signal_normalized)) {
// Cache the signal and using of it
signalCache[i] = float(signal_normalized);
signalCache[i] = static_cast<float>(signal_normalized);
useBox[i] = true;
// Get the coordinates.
size_t numVertexes = 0;
std::unique_ptr<coord_t> coords;
std::unique_ptr<coord_t[]> coords;
// If slicing down to 3D, specify which dimensions to keep.
if (this->slice) {
coords = std::unique_ptr<coord_t>(
coords = std::unique_ptr<coord_t[]>(
box->getVertexesArray(numVertexes, 3, this->sliceMask.get()));
} else {
coords = std::unique_ptr<coord_t>(box->getVertexesArray(numVertexes));
coords =
std::unique_ptr<coord_t[]>(box->getVertexesArray(numVertexes));
}
if (numVertexes == 8) {
// Iterate through all coordinates. Candidate for speed improvement.
for (size_t v = 0; v < numVertexes; v++) {
coord_t *coord = coords.get() + v * 3;
// Set the point at that given ID
points->SetPoint(i * 8 + v, coord[0], coord[1], coord[2]);
std::string msg;
}
} // valid number of vertexes returned
std::copy_n(coords.get(), 24, std::next(pointsPtr, i * 24));
}
} else {
useBox[i] = false;
}
......@@ -156,36 +154,28 @@ void vtkMDHexFactory::doCreate(
for (size_t i = 0; i < boxes.size(); i++) {
if (useBox[i]) {
// The bare point ID
vtkIdType pointIds = i * 8;
vtkIdType pointId = i * 8;
// Add signal
signals->InsertNextValue(signalCache[i]);
*signalsPtr = signalCache[i];
std::advance(signalsPtr, 1);
hexPointList->SetId(0, pointIds + 0); // xyx
hexPointList->SetId(1, pointIds + 1); // dxyz
hexPointList->SetId(2, pointIds + 3); // dxdyz
hexPointList->SetId(3, pointIds + 2); // xdyz
hexPointList->SetId(4, pointIds + 4); // xydz
hexPointList->SetId(5, pointIds + 5); // dxydz
hexPointList->SetId(6, pointIds + 7); // dxdydz
hexPointList->SetId(7, pointIds + 6); // xdydz
const std::array<vtkIdType, 8> idList{{0, 1, 3, 2, 4, 5, 7, 6}};
std::transform(
idList.begin(), idList.end(), hexPointList_ptr,
std::bind(std::plus<vtkIdType>(), std::placeholders::_1, pointId));
// Add cells
visualDataSet->InsertNextCell(VTK_HEXAHEDRON,
hexPointList.GetPointer());
double bounds[6];
visualDataSet->GetCellBounds(imageSizeActual, bounds);
if (bounds[0] < -10 || bounds[2] < -10 || bounds[4] < -10) {
std::string msg = "";
}
imageSizeActual++;
}
} // for each box.
// Shrink to fit
signals->Resize(imageSizeActual);
signals->Squeeze();
visualDataSet->Squeeze();
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment