1 /*========================================================================= 2 3 Program: Visualization Toolkit 4 Module: vtkIncrementalOctreePointLocator.h 5 6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 7 All rights reserved. 8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details. 9 10 This software is distributed WITHOUT ANY WARRANTY; without even 11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 12 PURPOSE. See the above copyright notice for more information. 13 14 =========================================================================*/ 15 // .NAME vtkIncrementalOctreePointLocator - Incremental octree in support 16 // of both point location and point insertion. 17 // 18 // .SECTION Description 19 // As opposed to the uniform bin-based search structure (adopted in class 20 // vtkPointLocator) with a fixed spatial resolution, an octree mechanism 21 // employs a hierarchy of tree-like sub-division of the 3D data domain. Thus 22 // it enables data-aware multi-resolution and accordingly accelerated point 23 // location as well as insertion, particularly when handling a radically 24 // imbalanced layout of points as not uncommon in datasets defined on 25 // adaptive meshes. Compared to a static point locator supporting pure 26 // location functionalities through some search structure established from 27 // a fixed set of points, an incremental point locator allows for, in addition, 28 // point insertion capabilities, with the search structure maintaining a 29 // dynamically increasing number of points. 30 // Class vtkIncrementalOctreePointLocator is an octree-based accelerated 31 // implementation of the functionalities of the uniform bin-based incremental 32 // point locator vtkPointLocator. For point location, an octree is built by 33 // accessing a vtkDataSet, specifically a vtkPointSet. For point insertion, 34 // an empty octree is inited and then incrementally populated as points are 35 // inserted. Three increasingly complex point insertion modes, i.e., direct 36 // check-free insertion, zero tolerance insertion, and non-zero tolerance 37 // insertion, are supported. In fact, the octree used in the point location 38 // mode is actually constructed via direct check-free point insertion. This 39 // class also provides a polygonal representation of the octree boundary. 40 // 41 // .SECTION See Also 42 // vtkAbstractPointLocator, vtkIncrementalPointLocator, vtkPointLocator, 43 // vtkMergePoints 44 45 #ifndef vtkIncrementalOctreePointLocator_h 46 #define vtkIncrementalOctreePointLocator_h 47 48 #include "vtkCommonDataModelModule.h" // For export macro 49 #include "vtkIncrementalPointLocator.h" 50 51 class vtkPoints; 52 class vtkIdList; 53 class vtkPolyData; 54 class vtkCellArray; 55 class vtkIncrementalOctreeNode; 56 57 class VTKCOMMONDATAMODEL_EXPORT vtkIncrementalOctreePointLocator : public vtkIncrementalPointLocator 58 { 59 public: 60 61 vtkTypeMacro( vtkIncrementalOctreePointLocator, vtkIncrementalPointLocator ); 62 void PrintSelf( ostream & os, vtkIndent indent ); 63 64 static vtkIncrementalOctreePointLocator * New(); 65 66 // Description: 67 // Set/Get the maximum number of points that a leaf node may maintain. 68 // Note that the actual number of points maintained by a leaf node might 69 // exceed this threshold if there is a large number (equal to or greater 70 // than the threshold) of exactly duplicate points (with zero distance) 71 // to be inserted (e.g., to construct an octree for subsequent point 72 // location) in extreme cases. Respecting this threshold in such scenarios 73 // would cause endless node sub-division. Thus this threshold is broken, but 74 // only in case of such situations. 75 vtkSetClampMacro( MaxPointsPerLeaf, int, 16, 256 ); 76 vtkGetMacro( MaxPointsPerLeaf, int ); 77 78 // Description: 79 // Set/Get whether the search octree is built as a cubic shape or not. 80 vtkSetMacro( BuildCubicOctree, int ); 81 vtkGetMacro( BuildCubicOctree, int ); 82 vtkBooleanMacro( BuildCubicOctree, int ); 83 84 // Description: 85 // Get access to the vtkPoints object in which point coordinates are stored 86 // for either point location or point insertion. 87 vtkGetObjectMacro( LocatorPoints, vtkPoints ); 88 89 // Description: 90 // Delete the octree search structure. Initialize()91 virtual void Initialize() { this->FreeSearchStructure(); } 92 93 // Description: 94 // Delete the octree search structure. 95 virtual void FreeSearchStructure(); 96 97 // Description: 98 // Get the spatial bounding box of the octree. 99 virtual void GetBounds( double * bounds ); 100 101 // Description: 102 // Get the spatial bounding box of the octree. GetBounds()103 virtual double * GetBounds() 104 { this->GetBounds( this->Bounds ); return this->Bounds; } 105 106 // Description: 107 // Get the number of points maintained by the octree. 108 int GetNumberOfPoints(); 109 110 // Description: 111 // Given a point x assumed to be covered by the octree, return the index of 112 // the closest in-octree point regardless of the associated minimum squared 113 // distance relative to the squared insertion-tolerance distance. This method 114 // is used when performing incremental point insertion. Note -1 indicates that 115 // no point is found. InitPointInsertion() should have been called in advance. 116 virtual vtkIdType FindClosestInsertedPoint( const double x[3] ); 117 118 // Description: 119 // Create a polygonal representation of the octree boundary (from the root 120 // node to a specified level). 121 virtual void GenerateRepresentation( int nodeLevel, vtkPolyData * polysData ); 122 123 // ------------------------------------------------------------------------- 124 // ---------------------------- Point Location ---------------------------- 125 // ------------------------------------------------------------------------- 126 127 // Description: 128 // Load points from a dataset to construct an octree for point location. 129 // This function resorts to InitPointInsertion() to fulfill some of the work. 130 virtual void BuildLocator(); 131 132 // Description: 133 // Given a point x, return the id of the closest point. BuildLocator() should 134 // have been called prior to this function. This method is thread safe if 135 // BuildLocator() is directly or indirectly called from a single thread first. 136 virtual vtkIdType FindClosestPoint( const double x[3] ); 137 138 // Description: 139 // Given a point (x, y, z), return the id of the closest point. Note that 140 // BuildLocator() should have been called prior to this function. This method 141 // is thread safe if BuildLocator() is directly or indirectly called from a 142 // single thread first. 143 virtual vtkIdType FindClosestPoint( double x, double y, double z ); 144 145 // Description: 146 // Given a point x, return the id of the closest point and the associated 147 // minimum squared distance (via miniDist2). Note BuildLocator() should have 148 // been called prior to this function. This method is thread safe if 149 // BuildLocator() is directly or indirectly called from a single thread first. 150 virtual vtkIdType FindClosestPoint( const double x[3], double * miniDist2 ); 151 152 // Description: 153 // Given a point (x, y, z), return the id of the closest point and the 154 // associated minimum squared distance (via miniDist2). BuildLocator() should 155 // have been called prior to this function. This method is thread safe if 156 // BuildLocator() is directly or indirectly called from a single thread first. 157 virtual vtkIdType FindClosestPoint( double x, double y, double z, double * miniDist2 ); 158 159 // Description: 160 // Given a point x and a radius, return the id of the closest point within 161 // the radius and the associated minimum squared distance (via dist2, this 162 // returned distance is valid only if the point id is not -1). Note that 163 // BuildLocator() should have been called prior to this function. This method 164 // is thread safe if BuildLocator() is directly or indirectly called from a 165 // single thread first. 166 virtual vtkIdType FindClosestPointWithinRadius 167 ( double radius, const double x[3], double & dist2 ); 168 169 // Description: 170 // Given a point x and a squared radius radius2, return the id of the closest 171 // point within the radius and the associated minimum squared distance (via 172 // dist2, note this returned distance is valid only if the point id is not 173 // -1). BuildLocator() should have been called prior to this function.This 174 // method is thread safe if BuildLocator() is directly or indirectly called 175 // from a single thread first. 176 vtkIdType FindClosestPointWithinSquaredRadius 177 ( double radius2, const double x[3], double & dist2 ); 178 179 // Description: 180 // Find all points within a radius R relative to a given point x. The returned 181 // point ids (stored in result) are not sorted in any way. BuildLocator() should 182 // have been called prior to this function. This method is thread safe if 183 // BuildLocator() is directly or indirectly called from a single thread first. 184 virtual void FindPointsWithinRadius 185 ( double R, const double x[3], vtkIdList * result ); 186 187 // Description: 188 // Find all points within a squared radius R2 relative to a given point x. The 189 // returned point ids (stored in result) are not sorted in any way. BuildLocator() 190 // should have been called prior to this function. This method is thread safe if 191 // BuildLocator() is directly or indirectly called from a single thread first. 192 void FindPointsWithinSquaredRadius 193 ( double R2, const double x[3], vtkIdList * result ); 194 195 // Description: 196 // Find the closest N points to a given point. The returned point ids (via 197 // result) are sorted from closest to farthest. BuildLocator() should have 198 // been called prior to this function. This method is thread safe if 199 // BuildLocator() is directly or indirectly called from a single thread first. 200 virtual void FindClosestNPoints 201 ( int N, const double x[3], vtkIdList * result ); 202 203 // ------------------------------------------------------------------------- 204 // ---------------------------- Point Insertion ---------------------------- 205 // ------------------------------------------------------------------------- 206 207 // Description: 208 // Initialize the point insertion process. points is an object, storing 3D 209 // point coordinates, to which incremental point insertion put coordinates. 210 // It is created and provided by an external VTK class. Argument bounds 211 // represents the spatial bounding box, into which the points fall. In fact, 212 // an adjusted version of the bounding box is used to build the octree to 213 // make sure no any point (to be inserted) falls outside the octree. This 214 // function is not thread safe. 215 virtual int InitPointInsertion( vtkPoints * points, const double bounds[6] ); 216 217 // Description: 218 // Initialize the point insertion process. points is an object, storing 3D 219 // point coordinates, to which incremental point insertion put coordinates. 220 // It is created and provided by an external VTK class. Argument bounds 221 // represents the spatial bounding box, into which the points fall. In fact, 222 // an adjusted version of the bounding box is used to build the octree to 223 // make sure no any point (to be inserted) falls outside the octree. Argument 224 // estSize specifies the initial estimated size of the vtkPoints object. This 225 // function is not thread safe. 226 virtual int InitPointInsertion( vtkPoints * points, const double bounds[6], 227 vtkIdType estSize ); 228 229 // Description: 230 // Determine whether or not a given point has been inserted into the octree. 231 // Return the id of the already inserted point if true, otherwise return -1. 232 // InitPointInsertion() should have been called in advance. 233 virtual vtkIdType IsInsertedPoint( const double x[3] ); 234 235 // Description: 236 // Determine whether or not a given point has been inserted into the octree. 237 // Return the id of the already inserted point if true, otherwise return -1. 238 // InitPointInsertion() should have been called in advance. 239 virtual vtkIdType IsInsertedPoint( double x, double y, double z ); 240 241 // Description: 242 // Insert a point to the octree unless there has been a duplciate point. 243 // Whether the point is actually inserted (return 1) or not (return 0 upon a 244 // rejection by an existing duplicate), the index of the point (either new 245 // or the duplicate) is returned via pntId. Note that InitPointInsertion() 246 // should have been called prior to this function. vtkPoints::InsertNextPoint() 247 // is invoked. This method is not thread safe. 248 virtual int InsertUniquePoint( const double point[3], vtkIdType & pntId ); 249 250 // Description: 251 // Insert a given point into the octree with a specified point index ptId. 252 // InitPointInsertion() should have been called prior to this function. In 253 // addition, IsInsertedPoint() should have been called in advance to ensure 254 // that the given point has not been inserted unless point duplication is 255 // allowed (Note that in this case, this function involves a repeated leaf 256 // container location). vtkPoints::InsertPoint() is invoked. 257 virtual void InsertPoint( vtkIdType ptId, const double x[3] ); 258 259 // Description: 260 // Insert a given point into the octree and return the point index. Note that 261 // InitPointInsertion() should have been called prior to this function. In 262 // addition, IsInsertedPoint() should have been called in advance to ensure 263 // that the given point has not been inserted unless point duplication is 264 // allowed (in this case, this function invovles a repeated leaf container 265 // location). vtkPoints::InsertNextPoint() is invoked. 266 virtual vtkIdType InsertNextPoint( const double x[3] ); 267 268 // Description: 269 // "Insert" a point to the octree without any checking. Argument insert means 270 // whether vtkPoints::InsertNextPoint() upon 1 is called or the point itself 271 // is not inserted to the vtkPoints at all but instead only the point index is 272 // inserted to a vtkIdList upon 0. For case 0, the point index needs to be 273 // specified via pntId. For case 1, the actual point index is returned via 274 // pntId. InitPointInsertion() should have been called. 275 void InsertPointWithoutChecking 276 ( const double point[3], vtkIdType & pntId, int insert ); 277 278 //BTX 279 protected: 280 281 vtkIncrementalOctreePointLocator(); 282 virtual ~vtkIncrementalOctreePointLocator(); 283 284 private: 285 286 int BuildCubicOctree; 287 int MaxPointsPerLeaf; 288 double InsertTolerance2; 289 double OctreeMaxDimSize; 290 double FudgeFactor; 291 vtkPoints * LocatorPoints; 292 vtkIncrementalOctreeNode * OctreeRootNode; 293 294 // Description: 295 // Delete all descendants of a node. 296 static void DeleteAllDescendants( vtkIncrementalOctreeNode * node ); 297 298 // Description: 299 // Add the polygonal representation of a given node to the allocated vtkPoints 300 // and vtkCellArray objects. 301 static void AddPolys( vtkIncrementalOctreeNode * node, 302 vtkPoints * points, vtkCellArray * polygs ); 303 304 // Description: 305 // Given a point and a reference node, find the leaf containing the point. 306 // Note the point is assumed to be inside or under the reference node. 307 vtkIncrementalOctreeNode * GetLeafContainer( vtkIncrementalOctreeNode * node, 308 const double pnt[3] ); 309 310 // Description: 311 // Given a point (under check, either inside or outside the octree) and a leaf 312 // node (not necessarily the container of this point), find the closest point 313 // (possibly a duplicate of the point under check) within the node and return 314 // the point index as well as the associated minimum squared distance (via dist2). 315 // InitPointInsertion() or BuildLocator() should have been called. 316 vtkIdType FindClosestPointInLeafNode( vtkIncrementalOctreeNode * leafNode, 317 const double point[3], double * dist2 ); 318 319 // Description: 320 // This function may not be directly called. Please use the follwing two ones: 321 // FindClosestPointInSphereWithTolerance() for point insertion and 322 // FindClosestPointInSphereWithoutTolerance() for point location. Arguments 323 // refDist2 and the initialization of minDist2 determine which version is used. 324 // Given a point (under check) and an already-checked node (possibly NULL), 325 // find the closest point across a set of neighboring nodes within a specified 326 // squared radius to the given point --- to perform an extended within-radius 327 // inter-node search. The leaf (mask) node itself is excluded from the search 328 // scope. Returned are the point index and the associated minimum squared 329 // distance. InitPointInsertion() or BuildLocator() should have been called. 330 vtkIdType FindClosestPointInSphere 331 ( const double point[3], double radius2, vtkIncrementalOctreeNode * maskNode, 332 double * minDist2, const double * refDist2 ); 333 334 335 // ------------------------------------------------------------------------- 336 // ---------------------------- Point Location ---------------------------- 337 // ------------------------------------------------------------------------- 338 339 // Description: 340 // This function is intended for point location, excluding point insertion. 341 // Given a point (under check, covered or uncovered by the octree) and an 342 // already-checked leaf node (maskNode, possibly NULL), find the closest point 343 // across a set of neighboring nodes within a specified squared radius to the 344 // given point --- to perform an extended within-radius inter-node search. The 345 // leaf (mask) node itself is excluded from the search scope. Returned are the 346 // point index and the associated minimum squared distance (via minDist2). Note 347 // that BuildLocator() should have been called. 348 vtkIdType FindClosestPointInSphereWithoutTolerance( const double point[3], 349 double radius2, vtkIncrementalOctreeNode * maskNode, double * minDist2 ); 350 351 // Description: 352 // Find all points, inside a given node, within a squared radius relative to 353 // a given point. Returned are the associated un-sorted point indices (idList). 354 // Note that BuildLocator() should have been called prior to this function. 355 void FindPointsWithinSquaredRadius( vtkIncrementalOctreeNode * node, 356 double radius2, const double point[3], vtkIdList * idList ); 357 358 // ------------------------------------------------------------------------- 359 // ---------------------------- Point Insertion ---------------------------- 360 // ------------------------------------------------------------------------- 361 362 // Description: 363 // This function is intended for point insertion, excluding point location. 364 // Given a point (under check for insertion, must be covered by the octree) 365 // and an already-checked node (maskNode, the container leaf node, possibly 366 // NULL if no any node has been checked), find the closest point across a set 367 // of neighbor nodes within a specified squared radius radius2 to the given 368 // point --- to perform an extended within-radius inter-node search. The leaf 369 // (mask) node itself is excluded from the search scope. Returned are the point 370 // index and the associated minimum squared distance (via minDist2). Note that 371 // InitPointInsertion() should have been called. 372 vtkIdType FindClosestPointInSphereWithTolerance( const double point[3], 373 double radius2, vtkIncrementalOctreeNode * maskNode, double * minDist2 ); 374 375 // Description: 376 // Determine whether or not a given point has been inserted into the octree. 377 // Return the id of the already inserted point if true, otherwise return -1. 378 // Argument leafContainer is useful for access only if -1 is returned. This 379 // returned parameter indicates the leaf node that contains the given point. 380 // This function resorts to IsInsertedPointForZeroTolerance() for zero 381 // tolerance insertion or IsInsertedPointForNonZeroTolerance() for non-zero 382 // tolerance insertion. InitPointInsertion() should have been called. 383 vtkIdType IsInsertedPoint( const double x[3], 384 vtkIncrementalOctreeNode ** leafContainer ); 385 386 // Description: 387 // Determine whether or not a given point has been inserted into the octree. 388 // Return the id of the already inserted point if true, otherwise return -1. 389 // Argument leafContainer is useful for access only if -1 is returned. This 390 // returned parameter indicates the leaf node that contains the given point. 391 // This variant is invoked by IsInsertedPoint(x, vtkIncrementalOctreeNode **) 392 // for zero tolerance insertion. InitPointInsertion() should have been called. 393 vtkIdType IsInsertedPointForZeroTolerance 394 ( const double x[3], vtkIncrementalOctreeNode ** leafContainer ); 395 396 // Description: 397 // Determine whether or not a given point has been inserted into the octree. 398 // Return the id of the already inserted point if true, otherwise return -1. 399 // Argument leafContainer is useful for access only if -1 is returned. This 400 // returned parameter indicates the leaf node that contains the given point. 401 // This variant is invoked by IsInsertedPoint(x, vtkIncrementalOctreeNode **) 402 // for non-zero tolerance insertion. InitPointInsertion() should have been 403 // called in advance. 404 vtkIdType IsInsertedPointForNonZeroTolerance 405 ( const double x[3], vtkIncrementalOctreeNode ** leafContainer ); 406 407 // Description: 408 // Given a point (under check for zero tolerance insertion) and a leaf node, 409 // find its duplicate, if any, in the node and return the point index (-1 if 410 // no duplicate is found). Note that the leaf node, already with at least one 411 // point, is the container of the point under check. InitPointInsertion() 412 // should have been called. 413 vtkIdType FindDuplicatePointInLeafNode( vtkIncrementalOctreeNode * leafNode, 414 const double point[3] ); 415 416 // Description: 417 // Given a point (under check for zero tolerance insertion) and a leaf node, 418 // find its duplicate, if any, in the node and return the point index (-1 if 419 // no duplicate is found). Note that the leaf node, already with at least one 420 // point, is the container of the point under check. This function is invoked 421 // for type VTK_FLOAT. InitPointInsertion() should have been called. 422 vtkIdType FindDuplicateFloatTypePointInVisitedLeafNode 423 ( vtkIncrementalOctreeNode * leafNode, const double point[3] ); 424 425 // Description: 426 // Given a point (under check for zero tolerance insertion) and a leaf node, 427 // find its duplicate, if any, in the node and return the point index (-1 if 428 // no duplicate is found). Note that the leaf node, already with at least one 429 // point, is the container of the point under check. This function is invoked 430 // for type VTK_DOUBLE. InitPointInsertion() should have been called. 431 vtkIdType FindDuplicateDoubleTypePointInVisitedLeafNode 432 ( vtkIncrementalOctreeNode * leafNode, const double point[3] ); 433 434 vtkIncrementalOctreePointLocator 435 ( const vtkIncrementalOctreePointLocator & ); // Not implemented 436 void operator = ( const vtkIncrementalOctreePointLocator & );// Not implemented 437 //ETX 438 }; 439 #endif 440