Commit b330bcce authored by bonnell's avatar bonnell
Browse files

Improve performance/accuracy of Picks on lines/line meshes in 3D

git-svn-id: http://visit.ilight.com/svn/visit/trunk/src@31222 18c085ea-50e0-402c-830e-de6fd14e8384
parent 6eea2337
......@@ -47,11 +47,11 @@
#include <vtkDataSet.h>
#include <vtkRectilinearGrid.h>
#include <vtkUnsignedCharArray.h>
#include <vtkVisItCellLocator.h>
#include <vtkVisItUtility.h>
#include <avtOriginatingSource.h>
#include <DebugStream.h>
#include <vtkVisItCellLocator.h>
#include <vtkVisItUtility.h>
#include <math.h>
#include <float.h>
......@@ -64,17 +64,17 @@
// Creation: November 15, 2002
//
// Modifications:
// Kathleen Bonnell, Fri Jan 31 11:34:03 PST 2003
// Kathleen Bonnell, Fri Jan 31 11:34:03 PST 2003
// Initialize minDist.
//
// Kathleen Bonnell, Mon Apr 14 09:43:11 PDT 2003
// Initialize invTransform.
// Kathleen Bonnell, Mon Apr 14 09:43:11 PDT 2003
// Initialize invTransform.
//
// Kathleen Bonnell, Thu Apr 17 09:39:19 PDT 2003
// Removed invTransform.
// Kathleen Bonnell, Thu Apr 17 09:39:19 PDT 2003
// Removed invTransform.
//
// Kathleen Bonnell, Wed Jun 2 10:21:50 PDT 2004
// Moved code to new parent class, avtLocateQuery.
// Kathleen Bonnell, Wed Jun 2 10:21:50 PDT 2004
// Moved code to new parent class, avtLocateQuery.
//
// ****************************************************************************
......@@ -107,71 +107,74 @@ avtLocateCellQuery::~avtLocateCellQuery()
// Purpose:
// Processes a single domain.
//
// Programmer: Kathleen Bonnell
// Programmer: Kathleen Bonnell
// Creation: November 15, 2002
//
// Modifications:
// Kathleen Bonnell, Fri Jan 31 11:34:03 PST 2003
// Kathleen Bonnell, Fri Jan 31 11:34:03 PST 2003
// Use ray endpoints to determine intersection point, via IntersectWithLine.
//
// Kathleen Bonnell, Wed Mar 26 13:03:54 PST 2003
// Kathleen Bonnell, Wed Mar 26 13:03:54 PST 2003
// Test if originalCells is set in DataAttributes, to indicate possible
// error condition if the array is not found in the dataset.
// error condition if the array is not found in the dataset.
//
// Kathleen Bonnell, Mon Apr 14 09:43:11 PDT 2003
// Kathleen Bonnell, Mon Apr 14 09:43:11 PDT 2003
// Use inverse transformation matrix, if available, to determine true
// intersection point with original data. Precludes necessity of using
// avtOriginalCellsArray.
//
// Kathleen Bonnell, Thu Apr 17 09:39:19 PDT 2003
// Don't use the transform matrix here, just test for its availability.
//
// Kathleen Bonnell, Wed May 7 13:06:55 PDT 2003
// For efficiency, do not use the cell locator for rectilinear grids.
//
// Kathleen Bonnell, Tue Jun 3 15:20:35 PDT 2003
//
// Kathleen Bonnell, Thu Apr 17 09:39:19 PDT 2003
// Don't use the transform matrix here, just test for its availability.
//
// Kathleen Bonnell, Wed May 7 13:06:55 PDT 2003
// For efficiency, do not use the cell locator for rectilinear grids.
//
// Kathleen Bonnell, Tue Jun 3 15:20:35 PDT 2003
// Removed calculation of tolerance, and passing of that value to FindCell
// methods. No longer use tolerance when calculating fudgedIsect.
//
//
// Kathleen Bonnell, Wed Jun 18 17:52:45 PDT 2003
// Always use OriginalCellsArray if present.
//
// Kathleen Bonnell, Fri Oct 10 11:45:24 PDT 2003
// Determine the picked node if in 'NodePick' mode.
//
// Kathleen Bonnell, Tue Nov 4 08:18:54 PST 2003
// Use pickAtts instead of queryAtts.
//
// Kathleen Bonnell, Thu May 6 14:28:00 PDT 2004
// Always use OriginalCellsArray if present.
//
// Kathleen Bonnell, Fri Oct 10 11:45:24 PDT 2003
// Determine the picked node if in 'NodePick' mode.
//
// Kathleen Bonnell, Tue Nov 4 08:18:54 PST 2003
// Use pickAtts instead of queryAtts.
//
// Kathleen Bonnell, Thu May 6 14:28:00 PDT 2004
// Set foundElement (used to set pickAtts.ElementNumber) to the foundCell
// if the zones have not been invalidated (ZonesPreserved).
//
// Kathleen Bonnell, Tue May 18 13:12:09 PDT 2004
// Move node-specific code to avtLocateNodeQuery.
// if the zones have not been invalidated (ZonesPreserved).
//
// Kathleen Bonnell, Tue May 18 13:12:09 PDT 2004
// Move node-specific code to avtLocateNodeQuery.
//
// Kathleen Bonnell, Wed Jul 7 14:48:44 PDT 2004
// Added call to FindClosestCell for line data.
// Kathleen Bonnell, Wed Jul 7 14:48:44 PDT 2004
// Added call to FindClosestCell for line data.
//
// Kathleen Bonnell, Tue Oct 5 14:02:31 PDT 2004
// Terminate early if the ray doesn't intersect the dataset.
// Kathleen Bonnell, Tue Oct 5 14:02:31 PDT 2004
// Terminate early if the ray doesn't intersect the dataset.
//
// Kathleen Bonnell, Wed Oct 20 17:10:21 PDT 2004
// Use vtkVisItUtility method for computing cell center.
// Kathleen Bonnell, Wed Oct 20 17:10:21 PDT 2004
// Use vtkVisItUtility method for computing cell center.
//
// Kathleen Bonnell, Fri Jul 8 14:15:21 PDT 2005
// Kathleen Bonnell, Fri Jul 8 14:15:21 PDT 2005
// Added another option when zones are preserved -- to determine
// whether the ghost zones are mixed (AMR & other types) or simply AMR --
// whether the ghost zones are mixed (AMR & other types) or simply AMR --
// will be used by PickQuery in determining the correct zone id to display
// to the user.
//
// Kathleen Bonnell, Wed Aug 10 17:00:58 PDT 2005
// Kathleen Bonnell, Wed Aug 10 17:00:58 PDT 2005
// Added some 'canUseCells' tests for whether or not to set the
// element number or determine cell center -- Added mostly because
// element number or determine cell center -- Added mostly because
// these things shouldn't be done if IndexSelected (the only operator
// currently to set this flag) -- the origCell may be invalid, the
// current cell number is most likely invalid, and the cell center is
// probably invalid as well, so defer the determination (other than
// domain and intersection point) until the Pick portion.
// domain and intersection point) until the Pick portion.
//
// Kathleen Biagas, Thu Jun 29 13:02:07 PDT 2017
// Remove constraint that lines should only be 2D spatially.
//
// ****************************************************************************
......@@ -190,8 +193,8 @@ avtLocateCellQuery::Execute(vtkDataSet *ds, const int dom)
avtDataObjectInformation &info = GetInput()->GetInfo();
avtDataAttributes &dataAtts = info.GetAttributes();
int dim = dataAtts.GetSpatialDimension();
int topodim = dataAtts.GetTopologicalDimension();
int spatdim = dataAtts.GetSpatialDimension();
int topodim = dataAtts.GetTopologicalDimension();
double dist = minDist, isect[3] = { 0., 0., 0.};
......@@ -201,21 +204,28 @@ avtLocateCellQuery::Execute(vtkDataSet *ds, const int dom)
//
if (ds->GetDataObjectType() != VTK_RECTILINEAR_GRID)
{
if (topodim == 1 && dim == 2) // Lines
foundCell = FindClosestCell(ds, dist, isect);
else
foundCell = LocatorFindCell(ds, dist, isect);
if (topodim == 1) // Lines
{
if (spatdim == 2)
foundCell = FindClosestCell(ds, dist, isect);
else if (spatdim == 3)
foundCell = ClosestLineToLine(ds, false, dist, isect);
}
else
{
foundCell = LocatorFindCell(ds, dist, isect);
}
}
else
{
foundCell = RGridFindCell(ds, dist, isect);
foundCell = RGridFindCell(ds, dist, isect);
}
if ((foundCell != -1) && (dist < minDist))
{
minDist = dist;
pickAtts.SetPickPoint(isect);
vtkDataArray *origCells =
vtkDataArray *origCells =
ds->GetCellData()->GetArray("avtOriginalCellNumbers");
bool canUseCells = dataAtts.CanUseOrigZones();
......@@ -224,13 +234,13 @@ avtLocateCellQuery::Execute(vtkDataSet *ds, const int dom)
int comp = origCells->GetNumberOfComponents() -1;
foundElement = (int) origCells->GetComponent(foundCell, comp);
}
else if (canUseCells && dataAtts.GetContainsOriginalCells())
else if (dataAtts.GetContainsOriginalCells() && !origCells)
{
debug5 << "PICK PROBLEM! Info says we should have original "
<< " cells but the array was not found in the dataset."
debug4 << "PICK PROBLEM! Info says we should have original "
<< "cells but the array was not found in the dataset."
<< endl;
}
else if (info.GetValidity().GetZonesPreserved())
else if (info.GetValidity().GetZonesPreserved())
{
if (dataAtts.GetContainsGhostZones() != AVT_CREATED_GHOSTS)
{
......@@ -245,11 +255,11 @@ avtLocateCellQuery::Execute(vtkDataSet *ds, const int dom)
}
//
// There is no need to 'fudge' the intersection point unless
// avtLocateCellQuery will be using it to find the Zone number and
// There is no need to 'fudge' the intersection point unless
// avtLocateCellQuery will be using it to find the Zone number and
// we are in 3D.
//
if (foundElement == -1 && dim == 3 && canUseCells)
if (foundElement == -1 && spatdim == 3 && canUseCells)
{
vtkVisItUtility::GetCellCenter(ds->GetCell(foundCell), isect);
}
......@@ -263,46 +273,46 @@ avtLocateCellQuery::Execute(vtkDataSet *ds, const int dom)
// Method: avtLocateCellQuery::RGridFindCell
//
// Purpose:
// Uses rectilinear-grid specific code to find the cell intersected by
// Uses rectilinear-grid specific code to find the cell intersected by
// the pick ray. Ignores ghost zones.
//
// Arguments:
// ds The dataset to query.
// dist A place to store the distance along the ray of the
// intersection point.
// isect A place to store the intersetion point of the ray with the
// dataset.
// dist A place to store the distance along the ray of the
// intersection point.
// isect A place to store the intersetion point of the ray with the
// dataset.
//
// Returns:
// The id of the cell that was intersected (-1 if none found).
//
// Programmer: Kathleen Bonnell
// Programmer: Kathleen Bonnell
// Creation: May 7, 2003
//
// Modifications:
// Kathleen Bonnell, Tue Jun 3 15:20:35 PDT 2003
// Removed unused tolerance parameter.
//
// Kathleen Bonnell, Wed Jul 23 15:51:45 PDT 2003
// Added logic for World pick (indicated by rayPoint1 == rayPoint2).
//
// Kathleen Bonnell, Tue Nov 4 08:18:54 PST 2003
// Use pickAtts instead of queryAtts.
//
// Kathleen Bonnell, Thu Feb 5 16:17:48 PST 2004
// Kathleen Bonnell, Wed Jul 23 15:51:45 PDT 2003
// Added logic for World pick (indicated by rayPoint1 == rayPoint2).
//
// Kathleen Bonnell, Tue Nov 4 08:18:54 PST 2003
// Use pickAtts instead of queryAtts.
//
// Kathleen Bonnell, Thu Feb 5 16:17:48 PST 2004
// Replaced vtkCell::HitBBox with vtkBox::IntersectBox, as the old
// method is soon to be obsoleted in vtk.
//
// Kathleen Bonnell, Wed Jun 2 10:21:50 PDT 2004
// Moved Isect code to RGridIsect.
// method is soon to be obsoleted in vtk.
//
// Kathleen Bonnell, Wed Jun 2 10:21:50 PDT 2004
// Moved Isect code to RGridIsect.
//
// Hank Childs, Fri Aug 27 16:02:58 PDT 2004
// Rename ghost data array.
//
// Kathleen Bonnell, Thu Oct 21 18:02:50 PDT 2004
// Kathleen Bonnell, Thu Oct 21 18:02:50 PDT 2004
// Correct test for whether a cell is ghost or not.
//
// Kathleen Bonnell, Thu Jun 23 11:33:53 PDT 2005
// Kathleen Bonnell, Thu Jun 23 11:33:53 PDT 2005
// Moved ghost-checking code to method RGridIsect, compressed code.
//
// ****************************************************************************
......@@ -310,7 +320,7 @@ avtLocateCellQuery::Execute(vtkDataSet *ds, const int dom)
int
avtLocateCellQuery::RGridFindCell(vtkDataSet *ds, double &dist, double *isect)
{
return RGridIsect(vtkRectilinearGrid::SafeDownCast(ds), dist, isect);
return RGridIsect(vtkRectilinearGrid::SafeDownCast(ds), dist, isect);
}
......@@ -318,25 +328,27 @@ avtLocateCellQuery::RGridFindCell(vtkDataSet *ds, double &dist, double *isect)
// Method: avtLocateQuery::FindClosestCell
//
// Purpose:
// Uses a locator to find the closest cell to the given point.
// Uses a locator to find the closest cell to the given point.
//
// Arguments:
// ds The dataset to query.
// minDist The current minimum distance.
// isect The intersection point.
// dist The current minimum distance.
// isect The intersection point.
//
// Returns:
// The id of the closest cell (-1 if none found).
//
// Programmer: Kathleen Bonnell
// Creation: July 7, 2004
// Programmer: Kathleen Bonnell
// Creation: July 7, 2004
//
// Modifications:
//
// Kathleen Biagas, Fri Jul 7 09:35:22 PDT 2017
// Changed arg from minDist to dist, to avoid overshadowing member var.
//
// ****************************************************************************
int
avtLocateCellQuery::FindClosestCell(vtkDataSet *ds, double &minDist, double isect[3])
avtLocateCellQuery::FindClosestCell(vtkDataSet *ds, double &dist, double isect[3])
{
if (ds->GetNumberOfPoints() == 0)
{
......@@ -345,7 +357,7 @@ avtLocateCellQuery::FindClosestCell(vtkDataSet *ds, double &minDist, double isec
vtkIdType foundCell = -1;
double *rayPt1 = pickAtts.GetRayPoint1();
double pt[3] = {rayPt1[0], rayPt1[1], 0.};
double dist, rad = minDist;
double dist2, rad = dist;
vtkVisItCellLocator *cellLocator = vtkVisItCellLocator::New();
cellLocator->SetDataSet(ds);
......@@ -354,18 +366,17 @@ avtLocateCellQuery::FindClosestCell(vtkDataSet *ds, double &minDist, double isec
int subId = 0;
double cp[3] = {0., 0., 0.};
int success = cellLocator->FindClosestPointWithinRadius(pt, rad, cp,
foundCell, subId, dist);
int success = cellLocator->FindClosestPointWithinRadius(pt, rad, cp,
foundCell, subId, dist2);
if (success == 1 && dist < minDist)
if (success == 1 && dist2 < dist)
{
isect[0] = cp[0];
isect[1] = cp[1];
isect[2] = cp[2];
minDist = dist;
dist = dist2;
}
cellLocator->Delete();
return foundCell;
}
......@@ -52,31 +52,31 @@ class vtkDataSet;
// Class: avtLocateCellQuery
//
// Purpose:
// This query locates a cell and domain given a world-coordinate point.
// This query locates a cell and domain given a world-coordinate point.
//
// Programmer: Kathleen Bonnell
// Creation: November 15, 2002
// Programmer: Kathleen Bonnell
// Creation: November 15, 2002
//
// Modifications:
// Kathleen Bonnell, Fri Jan 31 11:34:03 PST 2003
// Kathleen Bonnell, Fri Jan 31 11:34:03 PST 2003
// Added data member 'minDist'.
//
// Kathleen Bonnell, Mon Apr 14 09:43:11 PDT 2003
// Added member invTransform.
//
// Kathleen Bonnell, Thu Apr 17 09:39:19 PDT 2003
// Kathleen Bonnell, Thu Apr 17 09:39:19 PDT 2003
// Removed member invTransform.
//
// Kathleen Bonnell, Wed May 7 13:24:37 PDT 2003
// Kathleen Bonnell, Wed May 7 13:24:37 PDT 2003
// Add methods 'RGridFindCell' and 'LocatorFindCell'.
//
// Kathleen Bonnell, Tue Jun 3 15:20:35 PDT 2003
// Kathleen Bonnell, Tue Jun 3 15:20:35 PDT 2003
// Removed 'tolerance' parameter from FindCell methods.
//
// Kathleen Bonnell, Fri Oct 10 11:45:24 PDT 2003
// Added DeterminePickedNode.
// Added DeterminePickedNode.
//
// Kathleen Bonnell, Tue Nov 4 08:18:54 PST 2003
// Kathleen Bonnell, Tue Nov 4 08:18:54 PST 2003
// Added SetPickAtts, GetPickAtts, and PickAttributes data member.
//
// Hank Childs, Thu Feb 5 17:11:06 PST 2004
......@@ -84,11 +84,11 @@ class vtkDataSet;
// have problems with them.
//
// Kathleen Bonnell, Tue May 18 13:12:09 PDT 2004
// Inherit from avtLocateQuery. Moved Node specific code to
// avtLocateNodeQuery.
// Inherit from avtLocateQuery. Moved Node specific code to
// avtLocateNodeQuery.
//
// Kathleen Bonnell, Wed Jul 7 14:48:44 PDT 2004
// Added FindClosestCell, for use with line plots.
// Kathleen Bonnell, Wed Jul 7 14:48:44 PDT 2004
// Added FindClosestCell, for use with line plots.
//
// ****************************************************************************
......@@ -105,10 +105,10 @@ class QUERY_API avtLocateCellQuery : public avtLocateQuery
protected:
virtual void Execute(vtkDataSet *, const int);
int RGridFindCell(vtkDataSet *,
int RGridFindCell(vtkDataSet *,
double &, double*);
int FindClosestCell(vtkDataSet *ds,
double &minDist,
int FindClosestCell(vtkDataSet *ds,
double &dist,
double isect[3]);
};
......
......@@ -50,10 +50,10 @@
#include <vtkPoints.h>
#include <vtkRectilinearGrid.h>
#include <vtkUnsignedCharArray.h>
#include <vtkVisItPointLocator.h>
#include <avtGhostData.h>
#include <DebugStream.h>
#include <vtkVisItPointLocator.h>
#include <math.h>
#include <float.h>
......@@ -135,6 +135,9 @@ avtLocateNodeQuery::~avtLocateNodeQuery()
// not the node, pass along enough information for PickNode to possibly
// resolve the information.
//
// Kathleen Biagas, Thu Jun 29 13:02:07 PDT 2017
// Remove constraint that lines should only be 2D spatially.
//
// ****************************************************************************
void
......@@ -162,10 +165,13 @@ avtLocateNodeQuery::Execute(vtkDataSet *ds, const int dom)
//
if (ds->GetDataObjectType() != VTK_RECTILINEAR_GRID)
{
if (topodim == 1 && spatdim == 2) // LINES
if (topodim == 1) // LINES
{
dist = minDist;
foundNode = FindClosestPointOnLine(ds, dist, isect);
if (spatdim == 2)
foundNode = FindClosestPointOnLine(ds, dist, isect);
else if (spatdim == 3)
foundNode = ClosestLineToLine(ds, true, dist, isect);
}
else
{
......@@ -491,7 +497,8 @@ avtLocateNodeQuery::FindClosestPoint(vtkDataSet *ds, const int isectedCell,
//
// Arguments:
// ds The dataset to query.
// minDist The current minimum distance.
// dist The current minimum distance.
// isect The node coordinates.
//
// Returns:
// The id of the closest point (-1 if none found).
......@@ -504,16 +511,20 @@ avtLocateNodeQuery::FindClosestPoint(vtkDataSet *ds, const int isectedCell,
// Hank Childs, Thu Mar 10 10:27:57 PST 2005
// Fix memory leak.
//
// Kathleen Biagas, Fri Jul 7 09:35:22 PDT 2017
// Changed arg from minDist to dist, to avoid overshadowing member var.
//
// ****************************************************************************
int
avtLocateNodeQuery::FindClosestPointOnLine(vtkDataSet *ds, double &minDist,
avtLocateNodeQuery::FindClosestPointOnLine(vtkDataSet *ds, double &dist,
double isect[3])
{
if (ds->GetNumberOfPoints() == 0)
{
return -1;
}
double *rayPt1 = pickAtts.GetRayPoint1();
vtkVisItPointLocator *pointLocator = vtkVisItPointLocator::New();
......@@ -523,13 +534,13 @@ avtLocateNodeQuery::FindClosestPointOnLine(vtkDataSet *ds, double &minDist,
vtkIdType foundPoint = -1;
double pt[3] = {rayPt1[0], rayPt1[1], 0.};
double dist, rad = minDist;
double dist2, rad = dist;
foundPoint = pointLocator->FindClosestPointWithinRadius(rad, pt, dist);
if (foundPoint >= 0 && dist < minDist)
if (foundPoint >= 0 && dist2 < dist)
{
ds->GetPoint(foundPoint, isect);
minDist = dist;
dist = dist2;
}
pointLocator->Delete();
......
......@@ -52,16 +52,16 @@
// Class: avtLocateNodeQuery
//
// Purpose:
// This query locates a node and domain given a world-coordinate point.
// This query locates a node and domain given a world-coordinate point.
//
// Programmer: Kathleen Bonnell
// Creation: May 18, 2004
// Programmer: Kathleen Bonnell
// Creation: May 18, 2004
//
// Modifications:
// Kathleen Bonnell, Thu Jun 17 12:58:47 PDT 2004
// Added FindClosestPoint.
//
// Kathleen Bonnell, Wed Jul 7 14:59:49 PDT 2004
// Kathleen Bonnell, Wed Jul 7 14:59:49 PDT 2004
// Added FindClosestPointOnLine.
//
// ****************************************************************************
......@@ -79,16 +79,16 @@ class QUERY_API avtLocateNodeQuery : public avtLocateQuery
protected:
virtual void Execute(vtkDataSet *, const int);
int RGridFindNode(vtkDataSet *, double&,
int RGridFindNode(vtkDataSet *, double&,
double*);
int DeterminePickedNode(vtkDataSet *, int,
int DeterminePickedNode(vtkDataSet *, int,
double*);
int FindClosestPoint(vtkDataSet *, const int,
double*, int &);
int FindClosestPointOnLine(vtkDataSet *,
int FindClosestPointOnLine(vtkDataSet *,
double &,
double [3]);
};
......
......@@ -43,19 +43,23 @@
#include <avtLocateQuery.h>
#include <float.h>
#include <vtkBox.h>
#include <vtkCellData.h>
#include <vtkDataArray.h>
#include <vtkIdList.h>
#include <vtkLine.h>
#include <vtkMath.h>
#include <vtkPoints.h>
#include <vtkPointSet.h>
#include <vtkRectilinearGrid.h>
#include <vtkVisItCellLocator.h>
#include <vtkVisItUtility.h>
#include <NonQueryableInputException.h>
#include <avtOriginatingSource.h>
#include <avtExpressionEvaluatorFilter.h>
#include <avtOriginatingSource.h>
#include <avtParallel.h>
#include <DebugStream.h>
#include <NonQueryableInputException.h>
#include <vtkVisItCellLocator.h>
#include <vtkVisItUtility.h>
......@@ -63,7 +67,7 @@
// Method: avtLocateQuery constructor
//
// Programmer: Kathleen Bonnell
// Creation: May 18, 2004
// Creation: May 18, 2004
//
// Modifications:
//
......@@ -83,8 +87,8 @@ avtLocateQuery::avtLocateQuery()
// Defines the destructor. Note: this should not be inlined in the header
// because it causes problems for certain compilers.
//
// Programmer: Kathleen Bonnell
// Creation: May 18, 2004
// Programmer: Kathleen Bonnell
// Creation: May 18, 2004
//
// ****************************************************************************
......@@ -144,13 +148,13 @@ avtLocateQuery::PreExecute(void)
{
avtDatasetQuery::PreExecute();
foundElement = foundDomain = -1;
foundElement = foundDomain = -1;
minDist = +FLT_MAX;
avtDataAttributes &dAtts = GetInput()->GetInfo().GetAttributes();
if (dAtts.GetRectilinearGridHasTransform())
{
{