1 /**
2  * @class   vtkIntersectionCounter
3  * @brief   Fast simple class for dealing with ray intersections
4  *
5  * vtkIntersectionCounter is used to intersect data and merge coincident
6  * points along the intersect ray. It is light-weight and many of the member
7  * functions are in-lined so its very fast. It is not derived from vtkObject
8  * so it can be allocated on the stack.
9  *
10  * This class makes the finite ray intersection process more robust. It
11  * merges intersections that are very close to one another (within a
12  * tolerance). Such situations are common when intersection rays pass through
13  * the edge or vertex of a mesh.
14  *
15  * @sa
16  * vtkBoundingBox
17 */
18 
19 #ifndef vtkIntersectionCounter_h
20 #define vtkIntersectionCounter_h
21 
22 #include "vtkCommonDataModelModule.h" // For export macro
23 #include "vtkSystemIncludes.h"
24 #include <vector> // for implementation
25 #include <algorithm> // for sorting
26 
27 //class VTKCOMMONDATAMODEL_EXPORT vtkIntersectionCounter
28 
29 class vtkIntersectionCounter
30 {
31 public:
32   //@{
33   /**
34    * This tolerance must be converted to parametric space. Here tol is the
35    * tolerance in world coordinates; length is the ray length.
36    */
vtkIntersectionCounter()37   vtkIntersectionCounter() : Tolerance(0.0001) {}
vtkIntersectionCounter(double tol,double length)38   vtkIntersectionCounter(double tol, double length)
39   {
40     this->Tolerance = ( length > 0.0 ? (tol/length) : 0.0 );
41   }
42   //@}
43 
44   /**
45    * Set/Get the intersection tolerance.
46    */
SetTolerance(double tol)47   void SetTolerance(double tol)
48   { this->Tolerance = (tol < 0.0 ? 0.0001 : tol);}
GetTolerance()49   double GetTolerance() {return this->Tolerance;}
50 
51   /**
52    * Add an intersection given by parametric coordinate t.
53    */
AddIntersection(double t)54   void AddIntersection(double t) {IntsArray.push_back(t);}
55 
56   /**
57    * Reset the intersection process.
58    */
Reset()59   void Reset() {IntsArray.clear();}
60 
61   /**
62    * Returns number of intersections (even number of intersections, outside
63    * or odd number of intersections, inside). This is done by considering
64    * close intersections (within Tolerance) as being the same point.
65    */
CountIntersections()66   int CountIntersections()
67   {
68     int size = static_cast<int>(IntsArray.size());
69 
70     // Fast check for trivial cases
71     if ( size <= 1 )
72     {
73       return size; //0 or 1
74     }
75 
76     // Need to work harder: sort and then count the intersections
77     std::sort(IntsArray.begin(),IntsArray.end());
78 
79     // If here, there is at least one intersection, and two inserted
80     // intersection points
81     int numInts = 1;
82     std::vector<double>::iterator i0 = IntsArray.begin();
83     std::vector<double>::iterator i1 = i0 + 1;
84 
85     // Now march through sorted array counting "separated" intersections
86     while ( i1 != IntsArray.end() )
87     {
88       if ( (*i1 - *i0) > this->Tolerance )
89       {
90         numInts++;
91         i0 = i1;
92       }
93       i1++;
94     }
95 
96     return numInts;
97   }
98 
99 protected:
100   double Tolerance;
101   std::vector<double> IntsArray;
102 
103 }; // vtkIntersectionCounter
104 
105 #endif
106 // VTK-HeaderTest-Exclude: vtkIntersectionCounter.h
107