/*========================================================================= Program: Visualization Toolkit Module: vtkAbstractCellLocator.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 vtkAbstractCellLocator * @brief an abstract base class for locators which find cells * * vtkAbstractCellLocator is a spatial search object to quickly locate cells in 3D. * vtkAbstractCellLocator supplies a basic interface which concrete subclasses * should implement. * * @warning * When deriving a class from vtkAbstractCellLocator, one should include the * 'hidden' member functions by the following construct in the derived class * \verbatim * using vtkAbstractCellLocator::IntersectWithLine; * using vtkAbstractCellLocator::FindClosestPoint; * using vtkAbstractCellLocator::FindClosestPointWithinRadius; * using vtkAbstractCellLocator::FindCell; * \endverbatim * * @sa * vtkLocator vtkCellLocator vtkStaticCellLocator vtkCellTreeLocator vtkModifiedBSPTree vtkOBBTree */ #ifndef vtkAbstractCellLocator_h #define vtkAbstractCellLocator_h #include "vtkCommonDataModelModule.h" // For export macro #include "vtkDeprecation.h" // For VTK_DEPRECATED_IN_9_2_0 #include "vtkLocator.h" #include "vtkNew.h" // For vtkNew #include // For shared_ptr #include // For Weights class vtkCellArray; class vtkGenericCell; class vtkIdList; class vtkPoints; class VTKCOMMONDATAMODEL_EXPORT vtkAbstractCellLocator : public vtkLocator { public: vtkTypeMacro(vtkAbstractCellLocator, vtkLocator); void PrintSelf(ostream& os, vtkIndent indent) override; ///@{ /** * Specify the preferred/maximum number of cells in each node/bucket. * Default 32. Locators generally operate by subdividing space into * smaller regions until the number of cells in each region (or node) * reaches the desired level. */ vtkSetClampMacro(NumberOfCellsPerNode, int, 1, VTK_INT_MAX); vtkGetMacro(NumberOfCellsPerNode, int); ///@} ///@{ /** * Boolean controls whether the bounds of each cell are computed only * once and then saved. Should be 10 to 20% faster if repeatedly * calling any of the Intersect/Find routines and the extra memory * won't cause disk caching (48 extra bytes per cell are required to * save the bounds). */ vtkSetMacro(CacheCellBounds, vtkTypeBool); vtkGetMacro(CacheCellBounds, vtkTypeBool); vtkBooleanMacro(CacheCellBounds, vtkTypeBool); ///@} /** * This function can be used either internally or externally to compute only the cached * cell bounds if CacheCellBounds is on. */ void ComputeCellBounds(); ///@{ /** * Boolean controls whether to maintain list of cells in each node. * not applicable to all implementations, but if the locator is being used * as a geometry simplification technique, there is no need to keep them. */ vtkSetMacro(RetainCellLists, vtkTypeBool); vtkGetMacro(RetainCellLists, vtkTypeBool); vtkBooleanMacro(RetainCellLists, vtkTypeBool); ///@} ///@{ /** * Most Locators build their search structures during BuildLocator * but some may delay construction until it is actually needed. * If LazyEvaluation is supported, this turns on/off the feature. * if not supported, it is ignored. */ VTK_DEPRECATED_IN_9_2_0("This method is deprecated because it can lead to thread-safety issues") virtual void SetLazyEvaluation(vtkTypeBool) {} VTK_DEPRECATED_IN_9_2_0("This method is deprecated because it can lead to thread-safety issues") virtual vtkTypeBool GetLazyEvaluation() { return 0; } VTK_DEPRECATED_IN_9_2_0("This method is deprecated because it can lead to thread-safety issues") virtual void LazyEvaluationOn() {} VTK_DEPRECATED_IN_9_2_0("This method is deprecated because it can lead to thread-safety issues") virtual void LazyEvaluationOff() {} ///@} /** * Return intersection point (if any) of finite line with cells contained * in cell locator. See vtkCell.h parameters documentation. * * THIS FUNCTION IS NOT THREAD SAFE. */ virtual int IntersectWithLine(const double p1[3], const double p2[3], double tol, double& t, double x[3], double pcoords[3], int& subId); /** * Return intersection point (if any) AND the cell which was intersected by * the finite line. * * THIS FUNCTION IS NOT THREAD SAFE. */ virtual int IntersectWithLine(const double p1[3], const double p2[3], double tol, double& t, double x[3], double pcoords[3], int& subId, vtkIdType& cellId); /** * Return intersection point (if any) AND the cell which was intersected by * the finite line. The cell is returned as a cell id and as a generic cell. * * This function takes in a vtkGenericCell to avoid using the internal vtkGenericCell. * * THIS FUNCTION IS THREAD SAFE. */ virtual int IntersectWithLine(const double p1[3], const double p2[3], double tol, double& t, double x[3], double pcoords[3], int& subId, vtkIdType& cellId, vtkGenericCell* cell); /** * Take the passed line segment and intersect it with the data set. * The return value of the function is 0 if no intersections were found, * -1 if point 'a0' lies inside the closed surface, or +1 if point 'a0' * lies outside the closed surface. This method assumes that the data set * is a vtkPolyData that describes a closed surface, and the intersection * points that are returned in 'points' alternate between entrance points and exit points. * * Either 'points' or 'cellIds' can be set to nullptr if you don't want * to receive that information. * * This method is only implemented in vtkOBBTree. * * THIS FUNCTION IS THREAD SAFE. */ virtual int IntersectWithLine( const double p1[3], const double p2[3], vtkPoints* points, vtkIdList* cellIds); /** * Take the passed line segment and intersect it with the data set. * The return value of the function is 0 if no intersections were found. * For each intersection with a cell, the points and cellIds have the relevant information * added sorted by t. If points or cellIds are nullptr pointers, then no information is * generated for that list. * * THIS FUNCTION IS NOT THREAD SAFE. */ virtual int IntersectWithLine(const double p1[3], const double p2[3], const double tol, vtkPoints* points, vtkIdList* cellIds); /** * Take the passed line segment and intersect it with the data set. * The return value of the function is 0 if no intersections were found. * For each intersection with the bounds of a cell or with a cell (if a cell is provided), * the points and cellIds have the relevant information added sorted by t. * If points or cellIds are nullptr pointers, then no information is generated for that list. * * This function takes in a vtkGenericCell to avoid using the internal vtkGenericCell. * * THIS FUNCTION IS THREAD SAFE. */ virtual int IntersectWithLine(const double p1[3], const double p2[3], const double tol, vtkPoints* points, vtkIdList* cellIds, vtkGenericCell* cell); /** * Return the closest point and the cell which is closest to the point x. * The closest point is somewhere on a cell, it need not be one of the * vertices of the cell. * * A vtkAbstractCellLocator subclass needs to implement FindClosestPointWithinRadius * which is used internally to implement FindClosestPoint. * * THIS FUNCTION IS NOT THREAD SAFE. */ virtual void FindClosestPoint( const double x[3], double closestPoint[3], vtkIdType& cellId, int& subId, double& dist2); /** * Return the closest point and the cell which is closest to the point x. * The closest point is somewhere on a cell, it need not be one of the * vertices of the cell. * * A vtkAbstractCellLocator subclass needs to implement FindClosestPointWithinRadius * which is used internally to implement FindClosestPoint. * * This function takes in a vtkGenericCell to avoid using the internal vtkGenericCell. * * THIS FUNCTION IS THREAD SAFE. */ virtual void FindClosestPoint(const double x[3], double closestPoint[3], vtkGenericCell* cell, vtkIdType& cellId, int& subId, double& dist2); /** * Return the closest point within a specified radius and the cell which is * closest to the point x. The closest point is somewhere on a cell, it * need not be one of the vertices of the cell. This method returns 1 if * a point is found within the specified radius. If there are no cells within * the specified radius, the method returns 0 and the values of closestPoint, * cellId, subId, and dist2 are undefined. * * THIS FUNCTION IS NOT THREAD SAFE. */ virtual vtkIdType FindClosestPointWithinRadius(double x[3], double radius, double closestPoint[3], vtkIdType& cellId, int& subId, double& dist2); /** * Return the closest point within a specified radius and the cell which is * closest to the point x. The closest point is somewhere on a cell, it * need not be one of the vertices of the cell. This method returns 1 if * a point is found within the specified radius. If there are no cells within * the specified radius, the method returns 0 and the values of closestPoint, * cellId, subId, and dist2 are undefined. * * This function takes in a vtkGenericCell to avoid using the internal vtkGenericCell. * * THIS FUNCTION IS THREAD SAFE. */ virtual vtkIdType FindClosestPointWithinRadius(double x[3], double radius, double closestPoint[3], vtkGenericCell* cell, vtkIdType& cellId, int& subId, double& dist2); /** * Return the closest point within a specified radius and the cell which is * closest to the point x. The closest point is somewhere on a cell, it * need not be one of the vertices of the cell. This method returns 1 if a * point is found within the specified radius. If there are no cells within * the specified radius, the method returns 0 and the values of * closestPoint, cellId, subId, and dist2 are undefined. If a closest point * is found, inside returns the return value of the EvaluatePosition call to * the closest cell; inside(=1) or outside(=0). * * This function takes in a vtkGenericCell to avoid using the internal vtkGenericCell. * * THIS FUNCTION IS THREAD SAFE. */ virtual vtkIdType FindClosestPointWithinRadius(double x[3], double radius, double closestPoint[3], vtkGenericCell* cell, vtkIdType& cellId, int& subId, double& dist2, int& inside); /** * Return a list of unique cell ids inside of a given bounding box. The * user must provide the vtkIdList to populate. * * THIS FUNCTION IS THREAD SAFE. */ virtual void FindCellsWithinBounds(double* bbox, vtkIdList* cells); /** * Take the passed line segment and intersect it with the data set. * For each intersection with the bounds of a cell, the cellIds * have the relevant information added sort by t. If cellIds is nullptr * pointer, then no information is generated for that list. * * A vtkAbstractCellLocator subclass needs to implement IntersectWithLine that * takes cells ids, which is used internally to implement FindCellsAlongLine. * * THIS FUNCTION IS THREAD SAFE. */ virtual void FindCellsAlongLine( const double p1[3], const double p2[3], double tolerance, vtkIdList* cells); /** * Given an unbounded plane defined by an origin o[3] and unit normal n[3], * return the list of unique cell ids in the buckets containing the * plane. It is possible that an empty cell list is returned. The user must * provide the vtkIdList cell list to populate. This method returns data * only after the locator has been built. * * THIS FUNCTION IS THREAD SAFE. */ virtual void FindCellsAlongPlane( const double o[3], const double n[3], double tolerance, vtkIdList* cells); /** * Returns the Id of the cell containing the point, * returns -1 if no cell found. This interface uses a tolerance of zero * * THIS FUNCTION IS NOT THREAD SAFE. */ virtual vtkIdType FindCell(double x[3]); ///@{ /** * Find the cell containing a given point. returns -1 if no cell found * the cell parameters are copied into the supplied variables, a cell must * be provided to store the information. * * THIS FUNCTION IS THREAD SAFE. */ virtual vtkIdType FindCell( double x[3], double tol2, vtkGenericCell* GenCell, double pcoords[3], double* weights); virtual vtkIdType FindCell(double x[3], double tol2, vtkGenericCell* GenCell, int& subId, double pcoords[3], double* weights); ///@} /** * Quickly test if a point is inside the bounds of a particular cell. * Some locators cache cell bounds and this function can make use * of fast access to the data. This function should be used ONLY after the locator is built. */ virtual bool InsideCellBounds(double x[3], vtkIdType cell_ID); /** * Shallow copy of a vtkAbstractCellLocator. */ virtual void ShallowCopy(vtkAbstractCellLocator*) {} protected: vtkAbstractCellLocator(); ~vtkAbstractCellLocator() override; ///@{ /** * This command is used internally by the locator to copy * all cell Bounds into the internal CellBounds array. Subsequent * calls to InsideCellBounds(...) can make use of the data * A valid dataset must be present for this to work. Returns true * if bounds wre copied, false otherwise. */ virtual bool StoreCellBounds(); virtual void FreeCellBounds(); ///@} /** * To be called in `FindCell(double[3])`. If need be, the internal `Weights` array size is * updated to be able to host all points of the largest cell of the input data set. */ void UpdateInternalWeights(); int NumberOfCellsPerNode; vtkTypeBool RetainCellLists; vtkTypeBool CacheCellBounds; vtkNew GenericCell; std::shared_ptr> CellBoundsSharedPtr; double* CellBounds; // The is just used for simplicity in the internal code /** * This time stamp helps us decide if we want to update internal `Weights` array size. */ vtkTimeStamp WeightsTime; static bool IsInBounds(const double bounds[6], const double x[3], const double tol = 0.0); /* * This function should be used ONLY after the locator is built. * cellBoundsPtr should be assigned to a double cellBounds[6] BEFORE calling this function. */ void GetCellBounds(vtkIdType cellId, double*& cellBoundsPtr); /** * This array is resized so that it can fit points from the cell hosting the most in the input * data set. Resizing is done in `UpdateInternalWeights`. * * @note This array needs resized in `FindCell(double[3])`. */ std::vector Weights; private: vtkAbstractCellLocator(const vtkAbstractCellLocator&) = delete; void operator=(const vtkAbstractCellLocator&) = delete; }; #endif