Updates will be applied - 3:30pm EDT (UTC -400). No downtime expected.

Commit 6a81f6dd authored by Yohann Bearzi's avatar Yohann Bearzi

New overlapping cell detector filter

The new filter `vtkOverlappingCellsDetector` exposes overlapping cells
in an input `vtkDataSet`. It only works for linear cells.

Adresses paraview/paraview#19722
parent 73c7971b
......@@ -33,11 +33,6 @@ namespace detail
// the other cell.
int IntersectWithCell(vtkCell* self, vtkCell* other, double tol)
{
// Strategy:
// We throw edges from on cell to the other to look for intersections, and vice versa.
// If we catch one intersection, bingo.
//
// But first... we handle the case of a one point cell.
if (!other->GetNumberOfPoints() || !self->GetNumberOfPoints())
{
return 0;
......@@ -87,7 +82,6 @@ int IntersectWithCell(vtkCell* self, vtkCell* other, double tol)
ends->GetPoint(1, p2);
if (self->IntersectWithLine(p1, p2, tol, t, x, pcoords, subId))
{
std::cout << "second " << std::endl;
return 1;
}
}
......@@ -178,9 +172,9 @@ void vtkCell::Inflate(double dist)
}
std::vector<double> buf(3 * this->Points->GetNumberOfPoints(), 0.0);
vtkIdType pointId = 0;
auto pointRange = vtk::DataArrayTupleRange(this->Points->GetData());
auto pointRange = vtk::DataArrayTupleRange<3>(this->Points->GetData());
using TupleRef = typename decltype(pointRange)::TupleReferenceType;
auto stlPoints = vtk::DataArrayTupleRange(this->Points->GetData());
auto stlPoints = vtk::DataArrayTupleRange<3>(this->Points->GetData());
auto postPointIt = stlPoints.begin();
++postPointIt;
auto prePointIt = stlPoints.end();
......
......@@ -88,7 +88,7 @@ void vtkCell3D::Inflate(double dist)
double sign = this->IsInsideOut() ? -1.0 : 1.0;
double p[3];
vtkIdType pointId = 0;
auto pointRange = vtk::DataArrayTupleRange(this->Points->GetData());
auto pointRange = vtk::DataArrayTupleRange<3>(this->Points->GetData());
using ConstTupleRef = typename decltype(pointRange)::ConstTupleReferenceType;
for (ConstTupleRef point : pointRange)
{
......
......@@ -187,7 +187,7 @@ int vtkPixel::ComputeNormal(double n[3])
//----------------------------------------------------------------------------
void vtkPixel::Inflate(double dist)
{
auto range = vtk::DataArrayTupleRange(this->Points->GetData());
auto range = vtk::DataArrayTupleRange<3>(this->Points->GetData());
using TupleRef = typename decltype(range)::TupleReferenceType;
double n[3];
int normalDirection = this->ComputeNormal(n);
......
......@@ -192,7 +192,7 @@ void vtkVoxel::EvaluateLocation(
void vtkVoxel::Inflate(double dist)
{
int index = 0;
auto range = vtk::DataArrayTupleRange(this->Points->GetData());
auto range = vtk::DataArrayTupleRange<3>(this->Points->GetData());
using TupleRef = typename decltype(range)::TupleReferenceType;
for (TupleRef point : range)
{
......
......@@ -7,6 +7,7 @@ vtk_object_factory_declare(
set(classes
vtkAdaptiveResampleToImage
vtkOverlappingCellsDetector
vtkExtractSubsetWithSeed
vtkGenerateGlobalIds
vtkPResampleToImage
......
......@@ -2,6 +2,7 @@ vtk_module_test_data(
Data/multicomb_0.vts
Data/multicomb_1.vts
Data/multicomb_2.vts
Data/disk_out_ref.ex2)
Data/disk_out_ref.ex2
Data/overlapping_tetras.vtu)
add_subdirectory(Cxx)
......@@ -2,6 +2,7 @@ if (TARGET VTK::mpi)
set (vtkFiltersParallelDIY2CxxTests-MPI_NUMPROCS 2)
vtk_add_test_mpi(vtkFiltersParallelDIY2CxxTests-MPI tests
TESTING_DATA
TestOverlappingCellsDetector.cxx,NO_VALID
TestPResampleToImageCompositeDataSet.cxx
TestPResampleToImage.cxx
TestPResampleWithDataSet2.cxx
......@@ -28,8 +29,9 @@ endif()
# non-mpi tests
vtk_add_test_cxx(vtkFiltersParallelDIY2CxxTests non_mpi_tests
TestExtractSubsetWithSeed.cxx
TestAdaptiveResampleToImage.cxx,NO_VALID
TestExtractSubsetWithSeed.cxx
TestOverlappingCellsDetector.cxx,NO_VALID
TestGenerateGlobalIds.cxx,NO_VALID
TestRedistributeDataSetFilter.cxx,NO_VALID)
vtk_test_cxx_executable(vtkFiltersParallelDIY2CxxTests non_mpi_tests)
......@@ -34,9 +34,14 @@
namespace
{
static constexpr vtkIdType Collisions[72] = { 6, 0, 6, 0, 4, 4, 6, 0, 10, 7, 4, 0, 0, 7, 9, 0, 0, 5,
5, 0, 0, 0, 5, 9, 0, 6, 4, 6, 4, 4, 0, 6, 1, 0, 6, 9, 8, 7, 1, 9, 5, 0, 0, 5, 9, 7, 2, 3, 0, 0, 0,
0, 0, 6, 1, 4, 0, 1, 0, 0, 4, 0, 0, 0, 0, 0, 3, 6, 0, 0, 0, 0 };
static constexpr vtkIdType Collisions[72] = { 6, 0, 6, 0, 4, 4, 6, 0, 10, 7, // 0
4, 0, 0, 7, 9, 0, 0, 5, 5, 0, // 10
0, 0, 5, 9, 0, 6, 0, 6, 4, 4, // 20
0, 6, 1, 0, 4, 8, 7, 7, 1, 7, // 30
5, 0, 0, 5, 7, 5, 0, 2, 0, 0, // 40
0, 0, 0, 6, 1, 4, 0, 1, 0, 0, // 50
4, 0, 0, 0, 0, 0, 2, 6, 0, 0, // 60
0, 0 };
}
int TestOverlappingCellsDetector(int argc, char* argv[])
......@@ -74,20 +79,18 @@ int TestOverlappingCellsDetector(int argc, char* argv[])
vtkNew<vtkRedistributeDataSetFilter> redistribute;
redistribute->SetInputConnection(globalIds->GetOutputPort());
std::cout << myrank << "coucou " << std::endl;
vtkNew<vtkOverlappingCellsDetector> detector;
detector->SetInputConnection(redistribute->GetOutputPort());
detector->Update();
vtkDataSet* output = vtkDataSet::SafeDownCast(detector->GetOutput(0));
vtkDataArray* data =
output->GetCellData()->GetArray(vtkOverlappingCellsDetector::NumberOfCollisionsPerCell);
output->GetCellData()->GetArray(detector->GetNumberOfCollisionsPerCellArrayName());
vtkDataArray* ids = output->GetCellData()->GetArray("GlobalCellIds");
auto valIt = vtk::DataArrayValueRange<3>(data).cbegin();
auto idIt = vtk::DataArrayValueRange<3>(ids).cbegin();
for (; valIt != vtk::DataArrayValueRange<3>(data).cend(); ++valIt, ++idIt)
auto valIt = vtk::DataArrayValueRange(data).cbegin();
auto idIt = vtk::DataArrayValueRange(ids).cbegin();
for (; valIt != vtk::DataArrayValueRange(data).cend(); ++valIt, ++idIt)
{
if (Collisions[static_cast<vtkIdType>(*idIt)] != *valIt)
{
......
This diff is collapsed.
/*=========================================================================
Program: Visualization Toolkit
Module: vtkOverlappingCellsDetector.h
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm 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.
=========================================================================*/
/**
* @class vtkOverlappingCellsDetector
* @brief Exposes how many cells each cell of the input collide.
*
* This filter performs a cell collision detection between the cells of the input.
* This detection takes the form of a cell array of double. Its name can be
* reached from the static string attribute
* vtkOverlappingCellsDetector::NumberOfCollisionsPerCell.
*
* To detect collisions, coarse bounding spheres are estimated for each cell of the input.
* The center of those spheres is stored in a point cloud which is used to find potential
* colliding cells candidates, querying with twice the bounding sphere radius to ensure
* we do not miss other bouding sphere centers. Duplicate intersections might appear during
* this process, so a sphere id map is stored to avoid adding already added overlapping cell ids.
*
* This filter works in a multi-process environment. When so, each cell of the input
* whose bounding sphere and bounding box intersects another process is added in
* a temporary `vtkUnstructuredGrid` being sent to this process. Cell collision
* is then performed, and the collision id map is sent back. This map is then
* read to look if any of those cells were not already counted (local process
* could have spotted the same collision from
* the cells sent by the other process indeed). One cell id collision map is stored
* per neighbor process to avoid cell id collision.
*/
#ifndef vtkOverlappingCellsDetector_h
#define vtkOverlappingCellsDetector_h
#include "vtkFiltersParallelDIY2Module.h" // for export macros
#include "vtkPointSetAlgorithm.h"
#include "vtkBoundingBox.h" // For DetectOverlappingCells
#include <set> // For DetectOverlappingCells
#include <unordered_map> // For DetectOverlappingCells
#include <vector> // For DetectOverlappingCells
class vtkDataSet;
class vtkMultiProcessController;
class vtkPointSet;
class VTKFILTERSPARALLELDIY2_EXPORT vtkOverlappingCellsDetector : public vtkPointSetAlgorithm
{
public:
static vtkOverlappingCellsDetector* New();
vtkTypeMacro(vtkOverlappingCellsDetector, vtkPointSetAlgorithm);
void PrintSelf(ostream& os, vtkIndent indent) override;
//@{
/**
* Get/Set the controller to use. By default
* vtkMultiProcessController::GlobalController will be used.
*/
void SetController(vtkMultiProcessController*);
vtkGetObjectMacro(Controller, vtkMultiProcessController);
//@}
//@{
/**
* Getter / Setter for the name of the output array counting cell collisions.
* This array is a cell array.
*/
vtkGetStringMacro(NumberOfCollisionsPerCellArrayName);
vtkSetStringMacro(NumberOfCollisionsPerCellArrayName);
//@}
protected:
vtkOverlappingCellsDetector();
~vtkOverlappingCellsDetector() override;
int RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override;
/**
* Main pipeline. Performs cell collision detection in a MPI aware environment.
*/
int ExposeOverlappingCellsAmongBlocks(vtkPointSet* output);
/**
* Method performing the cell detection.
* There are 2 main types of inputs: query inputs, as well as inputs where to search.
* Points in point clouds represent bounding spheres of corresponding cell data set.
* Each point is associated with a radius.
* Bounding boxes must match the bounding boxes of corresponding cells in data sets.
*
* The algorithm goes as follows:
* - For each query point in queryPointCloud, a neighborhood is searched in pointCloud
* - For each neighbor found, a collision test is performed between query cell associated
* to query point and each cells associated with points found in the neighborhood.
* - If the test is positive, arrays of double associated with both datasets are
* incremented
*
* Last input CollisionListMaps is here to store the list of intersected cell ids from the query,
* mapped to the id of input cellDataSet. This object is used to avoid double counting
* collisions when sending back collision information to every block.
*
* This function can be called with queryCellDataSet and queryDataSet pointing to the same
* object in memory.
*
* Precondition: cellDataSet MUST have the cell array named NumberOfCollisionsPerCellArrayName()
*/
bool DetectOverlappingCells(vtkDataSet* queryCellDataSet, vtkPointSet* queryPointCloud,
const std::vector<vtkBoundingBox>& queryCellBoundingBoxes, vtkDataSet* cellDataSet,
vtkPointSet* pointCloud, const std::vector<vtkBoundingBox>& cellBoundingBoxes,
std::unordered_map<vtkIdType, std::set<vtkIdType>>& collisionListMap);
/**
* Local controller.
*/
vtkMultiProcessController* Controller;
/**
* Output cell scalar field counting the number of cells that each cell was found to collide.
*/
char* NumberOfCollisionsPerCellArrayName;
private:
vtkOverlappingCellsDetector(const vtkOverlappingCellsDetector&) = delete;
void operator=(const vtkOverlappingCellsDetector&) = delete;
};
#endif
d2063e3035a47d191a8e1966b1bd77553fcfe2f829c247643387e5eee4d72707d95d5a309c56010891b5765f67f93f8ffc3c8417295ee13d684090ba22a7add0
Markdown is supported
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