[vtkusers] vtkCellLocator::FindcellsAlongLine does not find all the cells

Alexander Pletzer alexander.pletzer at nesi.org.nz
Mon Jan 7 16:25:31 EST 2019


Hi VTK'ians,

I found vtkCellLocator to be a very fast way to locate  cells but I now
stumbled on an issue where the cell locator does not locate all the cells
along a line. In the code below, an unstructured 2x4x4 grid and
corresponding vtkCellLocator objects are created. The grid is a collection
of cells. A line is created that runs along the the bottom of the grid,
crossing all the latitudes and longitudes. Shown below are the bottom cells:

+----+----+----+----+
| 12 | 13 | *14* | *15* |
+----+----+----+----+
|  8 |  *9* | *10* | *11* |
+----+----+----+----+
|  *4* |  *5* |  *6* |  7 |
+----+----+----+----+
|  *0* |  *1* |  2 |  3 |
+----+----+----+----+

I would expect the number of cells found by FindCellsAlongLine to include
0, 5, 10 and 15 (red cells) as these cells are crossed by the line. Cells
1, 4, 6, 9, 11 and 14 touch the line so should also be found (blue cells).
The total number of cells is 10. When running the code (VTK 8.1.1 on mac) I
get:

...

1: line intersects with cell 0

1: line intersects with cell 1

1: line intersects with cell 4

1: line intersects with cell 5

1: line intersects with cell 6

1: line intersects with cell 9

1: line intersects with cell 10
1: line intersects with cell 14

 We see that cells 11 and 15 are missing! Other resolutions return the
correct list. I played with the tolerance in FindCellsAlongLine but this
seems to have no effect.

Any idea what I'm doing wrong? Thanks in advance.

--Alex

Test code:

#undef NDEBUG // turn on asserts
#include <vtkUnstructuredGrid.h>
#include <vtkCellLocator.h>
#include <vtkPoints.h>
#include <vtkIdList.h>
#include <vtkGenericCell.h>
#include <iostream>
#include <cmath>

void testLatLon(size_t nElv, size_t nLat, size_t nLon, const double pa[],
const double pb[]) {

    //
    // generate vertices
    //
    double p[3];

    double dElv = 1.0 / double(nElv);
    double dLat = 180.0 / double(nLat);
    double dLon = 360.0 / double(nLon);

    vtkPoints* points = vtkPoints::New();
    size_t nCells = nElv * nLat * nLon;
    points->SetDataTypeToDouble();
    points->SetNumberOfPoints(8 * nCells);

    vtkIdType index = 0;
    vtkIdType cellId = 0;
    for (size_t k = 0; k < nElv; ++k) {
        double elv0 = dElv*k;
        double elv1 = elv0 + dElv;
        for (size_t j = 0; j < nLat; ++j) {
            double lat0 = -90.0 + j*dLat;
            double lat1 = lat0 + dLat;
            for (size_t i = 0; i < nLon; ++i) {
                double lon0 = -180.0 + i*dLon;
                double lon1 = lon0 + dLon;

                p[0] = elv0; p[1] = lat0; p[2] = lon0;
                points->SetPoint(index, p);
                index++;

                p[0] = elv0; p[1] = lat0; p[2] = lon1;
                points->SetPoint(index, p);
                index++;

                p[0] = elv0; p[1] = lat1; p[2] = lon1;
                points->SetPoint(index, p);
                index++;

                p[0] = elv0; p[1] = lat1; p[2] = lon0;
                points->SetPoint(index, p);
                index++;

                p[0] = elv1; p[1] = lat0; p[2] = lon0;
                points->SetPoint(index, p);
                index++;

                p[0] = elv1; p[1] = lat0; p[2] = lon1;
                points->SetPoint(index, p);
                index++;

                p[0] = elv1; p[1] = lat1; p[2] = lon1;
                points->SetPoint(index, p);
                index++;

                p[0] = elv1; p[1] = lat1; p[2] = lon0;
                points->SetPoint(index, p);
                index++;

                std::cout << "cell " << cellId << ": elv = " << elv0 << "
-> " << elv1 <<
                             " lat = " << lat0 << " -> " << lat1 <<
                             " lon = " << lon0 << " -> " << lon1 << '\n';

                cellId++;
            }
        }
    }

    //
    // create grid
    //
    vtkUnstructuredGrid* grid = vtkUnstructuredGrid::New();
    grid->SetPoints(points);
    grid->Allocate(1, 1);
    vtkIdList* ptIds = vtkIdList::New();
    ptIds->SetNumberOfIds(8);
    for (size_t iCell = 0; iCell < nCells; ++iCell) {
        for (vtkIdType iVert = 0; iVert < 8; ++iVert) {
            ptIds->SetId(iVert, 8*iCell + iVert);
        }
        grid->InsertNextCell(VTK_HEXAHEDRON, ptIds);
        std::cout << "inserting cell " << iCell;
        for (vtkIdType iVert = 0; iVert < 8; ++iVert) {
          vtkIdType vi = ptIds->GetId(iVert);
          double vrtx[3];
          points->GetPoint(vi, vrtx);
          std::cout << "\t" << iVert << " vert index: " << vi <<
          " vert coords: " << vrtx[0] << ',' << vrtx[1] << ',' << vrtx[2]
<< '\n';
        }
    }

    vtkCellLocator* loc = vtkCellLocator::New();
    loc->SetDataSet(grid);
    loc->BuildLocator();

    // find all the cells allong the line
    vtkIdList* cellIds = vtkIdList:: New();
    double tol = 0.01;
    loc->FindCellsAlongLine((double*) pa, (double*) pb, tol, cellIds);
    for (vtkIdType i = 0; i < cellIds->GetNumberOfIds(); ++i) {
      std::cout << "line intersects with cell " << cellIds->GetId(i) <<
'\n';
    }

    // clean up
    cellIds->Delete();
    loc->Delete();
    ptIds->Delete();
    grid->Delete();
    points->Delete();
}


int main(int argc, char** argv) {

    double pa[] = {0., -90., -180.};
    double pb[] = {0., 90., 180.};
    testLatLon(2, 4, 4, pa, pb);

    return 0;
}






-- 
Alexander Pletzer
HPC Scientific Programmer for New Zealand eScience Infrastructure (NeSI),
Wellington NZ
mobile: +64 21 085 79661
http://www. <http://www.niwa.co.nz>nesi.org.nz
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://vtk.org/pipermail/vtkusers/attachments/20190108/bba5b4ee/attachment.html>


More information about the vtkusers mailing list