1 // Copyright 2006-2009 Brad King, Chuck Stewart
2 // Distributed under the Boost Software License, Version 1.0.
3 // (See accompanying file rgtl_license_1_0.txt or copy at
4 // http://www.boost.org/LICENSE_1_0.txt)
5 #ifndef rgtl_sqt_objects_hxx
6 #define rgtl_sqt_objects_hxx
7 
8 #include <limits>
9 #include <iostream>
10 #include <memory>
11 #include <cstdlib>
12 #include <cmath>
13 #ifdef _MSC_VER
14 #  include <vcl_msvc_warnings.h>
15 #endif
16 #include "rgtl_sqt_objects.h"
17 
18 #include "rgtl_config.h"
19 #include "rgtl_object_array.h"
20 #include "rgtl_object_once.h"
21 #include "rgtl_octree_data_fixed.hxx"
22 #include "rgtl_sqt_cell_bounds.h"
23 #include "rgtl_sqt_cell_geometry.h"
24 #include "rgtl_sqt_cell_location.h"
25 #include "rgtl_sqt_object_array.h"
26 #include "rgtl_sqt_space.hxx"
27 #include "rgtl_serialize_access.h"
28 #include "rgtl_serialize_base.h"
29 #include "rgtl_serialize_vnl_vector_fixed.h"
30 #include "rgtl_serialize_istream.h"
31 #include "rgtl_serialize_ostream.h"
32 
33 #include <vnl/vnl_math.h>
34 #include <vnl/vnl_vector_fixed.h>
35 
36 #include <cassert>
37 
38 // TODO: During tree construction we should check the set of objects
39 // in the current node.  Those with no boundary inside the node should
40 // be left out of the count of objects remaining because no amount of
41 // subdivision will reduce the count.
42 
43 //#define RGTL_SQT_OBJECTS_DEBUG_BUILD
44 //#define RGTL_SQT_OBJECTS_DEBUG_BUILD2
45 //#define RGTL_SQT_OBJECTS_DEBUG_QUERY
46 
47 #if defined(RGTL_SQT_OBJECTS_DEBUG_BUILD) || \
48     defined(RGTL_SQT_OBJECTS_DEBUG_BUILD2) || \
49     defined(RGTL_SQT_OBJECTS_DEBUG_QUERY) || 0
50 # include <std::iostream.h>
51 # include <std::exception.h>
52 #endif
53 
54 //----------------------------------------------------------------------------
55 // All cells store bounding information.
56 template <unsigned int D>
57 struct rgtl_sqt_objects_cell_data
58 {
59   typedef float cone_bounds_type;
60   cone_bounds_type depth_min;
61   cone_bounds_type depth_max;
62   cone_bounds_type cone_axis[D];
63   cone_bounds_type cone_angle;
64  private:
65   friend class rgtl_serialize_access;
66   template <class Serializer>
serializergtl_sqt_objects_cell_data67   void serialize(Serializer& sr)
68   {
69     sr & depth_min;
70     sr & depth_max;
71     sr & cone_axis;
72     sr & cone_angle;
73   }
74 };
75 
76 // Leaves hold per-cell information and also store objects.
77 template <unsigned int D>
78 struct rgtl_sqt_objects_leaf_data: public rgtl_sqt_objects_cell_data<D>
79 {
80   typedef rgtl_sqt_objects_cell_data<D> derived;
81   typedef int index_type;
82 
83   // Store the begin and end index into a list of object ids
84   // associated with the tree in which this leaf is stored.
85   index_type index_begin;
86   index_type index_end;
87 
rgtl_sqt_objects_leaf_datargtl_sqt_objects_leaf_data88   rgtl_sqt_objects_leaf_data() {}
rgtl_sqt_objects_leaf_datargtl_sqt_objects_leaf_data89   rgtl_sqt_objects_leaf_data(index_type begin, index_type end):
90     index_begin(begin), index_end(end) {}
91  private:
92   friend class rgtl_serialize_access;
93   template <class Serializer>
serializergtl_sqt_objects_leaf_data94   void serialize(Serializer& sr)
95   {
96     sr & rgtl_serialize_base<derived>(*this);
97     sr & index_begin;
98     sr & index_end;
99   }
100 };
101 
102 // Nodes hold per-cell information.
103 template <unsigned int D>
104 struct rgtl_sqt_objects_node_data: public rgtl_sqt_objects_cell_data<D>
105 {
106   typedef rgtl_sqt_objects_cell_data<D> derived;
107  private:
108   friend class rgtl_serialize_access;
109   template <class Serializer>
serializergtl_sqt_objects_node_data110   void serialize(Serializer& sr)
111   {
112     sr & rgtl_serialize_base<derived>(*this);
113   }
114 };
115 
116 //----------------------------------------------------------------------------
117 // Method helper object forward declarations.
118 template <unsigned int D> class rgtl_sqt_objects_query_closest;
119 template <unsigned int D, unsigned int Face>
120 class rgtl_sqt_objects_query_closest_face;
121 
122 //----------------------------------------------------------------------------
123 // Superclass for typed per-face implementation of spatial structure.
124 template <unsigned int D>
125 class rgtl_sqt_objects_face_base
126 {
127  public:
128   // Type stored in tree leaves.
129   typedef rgtl_sqt_objects_leaf_data<D> leaf_data_type;
130 
131   // Type stored in tree nodes.
132   typedef rgtl_sqt_objects_node_data<D> node_data_type;
133 
134   // The type of the quad-tree itself.
135   typedef rgtl_octree_data_fixed<D-1,
136                                  leaf_data_type, node_data_type> tree_type;
137 
138   // Type-safe cell index in quad-tree representation.
139   typedef typename tree_type::cell_index_type cell_index_type;
140 
141   // Type-safe child index in quad-tree representation.
142   typedef typename tree_type::child_index_type child_index_type;
143 
144   // Type of logical SQT cell location.
145   typedef rgtl_sqt_cell_location<D> cell_location_type;
146 
147   // Type representing SQT cell parameter bounds.
148   typedef rgtl_sqt_cell_bounds<D> cell_bounds_type;
149 
150   // Full spatial structure internal representation type.
151   typedef rgtl_sqt_objects_internal<D> internal_type;
152 
153   // Type representing the original array of objects stored.
154   typedef typename internal_type::object_array_type object_array_type;
155 
156   // Type of pointer to set of objects during construction.
157   typedef std::unique_ptr< rgtl_sqt_object_set<D> > sqt_object_set_ptr;
158 
159   // Construct with reference to main internal representation.
rgtl_sqt_objects_face_base(internal_type & intern)160   rgtl_sqt_objects_face_base(internal_type& intern): internal_(intern) {}
161 
162   // Build the spatial structure in this face.
163   virtual void build(sqt_object_set_ptr&) = 0;
164 
165   // Convert a direction in this face to parameters.
166   virtual void direction_to_parameters(double const d[D],
167                                        double u[D-1]) const = 0;
168 
169   // Query a ray contained in this face.
170   virtual bool query_ray(double const d[D], double x[D], double* s) const = 0;
171 
172   virtual void query_closest(double const p[D], int k, double const u[D-1],
173                              rgtl_sqt_objects_query_closest<D>& qc) const = 0;
174 
175   // Access the tree representation for this face.
tree()176   tree_type& tree() { return this->tree_; }
tree() const177   tree_type const& tree() const { return this->tree_; }
178 
179  protected:
180   // Reference the full spatial structure internal implementation that
181   // owns this face.
182   internal_type& internal_;
183 
184   // The actual quad-tree structure for this face.
185   tree_type tree_;
186 
187   // Leaf data stores index ranges into this array which maps to the
188   // object ids in each leaf.
189   std::vector<int> object_ids_;
190 
191  private:
192   friend class rgtl_serialize_access;
serialize(Serializer & sr)193   template <class Serializer> void serialize(Serializer& sr)
194   {
195     sr & tree_;
196     sr & object_ids_;
197   }
198 };
199 
200 // Implementation of spatial structure for a single face.
201 template <unsigned int D, unsigned int Face>
202 class rgtl_sqt_objects_face: public rgtl_sqt_objects_face_base<D>
203 {
204  public:
205   typedef rgtl_sqt_objects_face_base<D> derived;
206 
207   // Promote type names from superclass.
208   typedef typename derived::leaf_data_type leaf_data_type;
209   typedef typename derived::node_data_type node_data_type;
210   typedef typename derived::tree_type tree_type;
211   typedef typename derived::cell_index_type cell_index_type;
212   typedef typename derived::child_index_type child_index_type;
213   typedef typename derived::cell_location_type cell_location_type;
214   typedef typename derived::cell_bounds_type cell_bounds_type;
215   typedef typename derived::internal_type internal_type;
216   typedef typename derived::object_array_type object_array_type;
217 
218   // Type maintaining SQT cell geometry as the tree is traversed.
219   typedef rgtl_sqt_cell_geometry<D, Face> cell_geometry_type;
220 
221   // Construct empty tree with reference to full spatial structure
222   // instance holding this per-face instance.
rgtl_sqt_objects_face(internal_type & intern)223   rgtl_sqt_objects_face(internal_type& intern): derived(intern) {}
224 
225   // Pointer type for object set base class.
226   typedef std::unique_ptr< rgtl_sqt_object_set<D> > sqt_object_set_ptr;
227 
228   // Pointer type for object set representation in this face.
229   typedef std::unique_ptr< rgtl_sqt_object_set_face<D, Face> >
230   sqt_object_set_face_ptr;
231 
232   // Spatial parameterization for this face.
233   typedef rgtl_sqt_space<D, Face> space;
234 
235   // Convert a direction in this face to parameters.
direction_to_parameters(double const d[D],double u[D-1]) const236   virtual void direction_to_parameters(double const d[D],
237                                        double u[D-1]) const
238   {
239     space::direction_to_parameters(d, u);
240   }
241 
242   // Build the spatial structure in this face.
243   virtual void build(sqt_object_set_ptr& oa);
244 
245   // Query a ray contained in this face.
246   virtual bool query_ray(double const d[D], double x[D], double* s) const;
247 
248   virtual void query_closest(double const p[D], int k, double const u[D-1],
249                              rgtl_sqt_objects_query_closest<D>& qc) const;
250 
251 #ifdef RGTL_SQT_OBJECTS_DEBUG_BUILD2
252   class exception_stack
253   {
254    public:
exception_stack(cell_location_type const & cell)255     exception_stack(cell_location_type const& cell):
256       cell_(cell), msg_(""), sz1_(0) {}
set_message(const char * msg)257     void set_message(const char* msg) { this->msg_ = msg; }
set_size1(unsigned int sz1)258     void set_size1(unsigned int sz1) { this->sz1_ = sz1; }
~exception_stack()259     ~exception_stack()
260     {
261       if (std::uncaught_exception())
262       {
263         std::cerr << "  " << cell_ << " (" << this->sz1_
264                  << ") " << this->msg_ << '\n';
265       }
266     }
267    private:
268     cell_location_type const& cell_;
269     const char* msg_;
270     unsigned int sz1_;
271   };
272 #endif
273 
274  private:
275   // Recursive method to actually build the spatial structure in this face.
276   void build(cell_geometry_type const& cell_geometry,
277              cell_index_type cell_index,
278              sqt_object_set_face_ptr& oa);
279 
280   // Recursive implementation of ray query.
281   bool query_ray(cell_location_type const& cell, cell_index_type cell_index,
282                  double const u[D-1], double const d[D], double x[D],
283                  double* s) const;
284   bool query_ray(int id, double const d[D], double x[D], double* s) const;
285 
286   // Access methods for internal representation.
object_array() const287   object_array_type const& object_array() const
288   { return this->internal_.object_array(); }
origin() const289   vnl_vector_fixed<double,D> const& origin() const
290   { return this->internal_.origin(); }
291 
292   friend class rgtl_sqt_objects_query_closest_face<D, Face>;
293 
294   friend class rgtl_serialize_access;
295   template <class Serializer>
serialize(Serializer & sr)296   void serialize(Serializer& sr)
297   {
298     sr & rgtl_serialize_base<derived>(*this);
299   }
300 };
301 
302 //----------------------------------------------------------------------------
303 // Template container to hold a typed object for each face.
304 template <unsigned int D, unsigned int Face> class rgtl_sqt_objects_faces;
305 
306 // Base class for face container.  Does not hold any faces but is used
307 // to terminate recursive instantiation.
308 template <unsigned int D>
309 class rgtl_sqt_objects_faces_base
310 {
311  public:
rgtl_sqt_objects_faces_base(rgtl_sqt_objects_internal<D> &,rgtl_sqt_objects_face_base<D> * [(D<<1)])312   rgtl_sqt_objects_faces_base(rgtl_sqt_objects_internal<D>&,
313                               rgtl_sqt_objects_face_base<D>* [(D<<1)]) {}
314  private:
315   friend class rgtl_serialize_access;
serialize(Serializer &)316   template <class Serializer> void serialize(Serializer&) {}
317 };
318 
319 // Template to lookup the next holding type for the next face.
320 template <unsigned int Face> struct rgtl_sqt_objects_face_next
321 {
322   template <unsigned int D>
323   struct get { typedef rgtl_sqt_objects_faces<D, Face-1> type; };
324 };
325 
326 template <> struct rgtl_sqt_objects_face_next<0>
327 {
328   template <unsigned int D>
329   struct get { typedef rgtl_sqt_objects_faces_base<D> type; };
330 };
331 
332 template <unsigned int D, unsigned int Face>
333 class rgtl_sqt_objects_faces
334 : public rgtl_sqt_objects_face_next<Face>::template get<D>::type
335 {
336  public:
337   // Superclass holds additional faces.
338   typedef typename
339   rgtl_sqt_objects_face_next<Face>::template get<D>::type derived;
340 
341   // Construct a face and provide a pointer to it.
rgtl_sqt_objects_faces(rgtl_sqt_objects_internal<D> & intern,rgtl_sqt_objects_face_base<D> * p[(D<<1)])342   rgtl_sqt_objects_faces(rgtl_sqt_objects_internal<D>& intern,
343                          rgtl_sqt_objects_face_base<D>* p[(D<<1)])
344   : derived(intern, p), face_(intern)
345   {
346     p[Face] = &face_;
347   }
348  private:
349   // Hold a face instance.
350   rgtl_sqt_objects_face<D, Face> face_;
351 
352   friend class rgtl_serialize_access;
353   template <class Serializer>
serialize(Serializer & sr)354   void serialize(Serializer& sr)
355   {
356     sr & rgtl_serialize_base<derived>(*this);
357     sr & face_;
358   }
359 };
360 
361 //----------------------------------------------------------------------------
362 template <unsigned int D>
363 class rgtl_sqt_objects_internal
364 {
365  public:
366   // Type holding original array of objects stored.
367   typedef rgtl_object_array<D> object_array_type;
368 
369   // Type holding SQT-specific representation of object array.
370   typedef rgtl_sqt_object_array<D> sqt_object_array_type;
371   typedef std::unique_ptr<sqt_object_array_type> sqt_object_array_ptr;
372 
373   // Type holding SQT-specific representation of object set during
374   // cell construction.
375   typedef rgtl_sqt_object_set<D> sqt_object_set_type;
376   typedef std::unique_ptr<sqt_object_set_type> sqt_object_set_ptr;
377 
378   // Default constructor.
379   rgtl_sqt_objects_internal(object_array_type const& original_objs);
380 
381   // Constructor for SQT-specific representation of input object array.
382   void build(sqt_object_array_type const& objs,
383              double const origin[D], int ml, int mpl);
384 
385   // Get the implementation object for a given face index.
face(unsigned int i)386   rgtl_sqt_objects_face_base<D>& face(unsigned int i)
387   {
388     return *faces_[i];
389   }
face(unsigned int i) const390   rgtl_sqt_objects_face_base<D> const& face(unsigned int i) const
391   {
392     return *faces_[i];
393   }
394 
395   // Get tree building parameters.
max_level() const396   int max_level() const { return this->max_level_; }
max_per_leaf() const397   int max_per_leaf() const { return this->max_per_leaf_; }
398 
399   // Get the original object array.
object_array() const400   object_array_type const& object_array() const
401   { return this->object_array_; }
402 
403   // Get the SQT guard position.  This is also the origin of all sight rays.
origin() const404   vnl_vector_fixed<double,D> const& origin() const { return this->origin_; }
origin(unsigned int a) const405   double origin(unsigned int a) const { return this->origin_[a]; }
406 
407   // External interface method implementations.
408   bool query_ray(double const d[D], double x[D], double* s) const;
409   int query_closest(double const p[D], int k, int* ids,
410                     double* squared_distances, double* points,
411                     double bound_squared) const;
412 
number_of_objects() const413   int number_of_objects() const
414   {
415     return this->object_array_.number_of_objects();
416   }
417 
object_closest_point(int id,double const x[D],double y[D],double bound_squared) const418   bool object_closest_point(int id,
419                             double const x[D],
420                             double y[D],
421                             double bound_squared) const
422   {
423     return this->object_array_.object_closest_point(id, x, y, bound_squared);
424   }
425 
visit_once(int id) const426   bool visit_once(int id) const
427   {
428     return this->object_once_.visit(id);
429   }
430 
431 #ifdef RGTL_SQT_OBJECTS_DEBUG_QUERY
set_query_closest_debug(bool b)432   void set_query_closest_debug(bool b) { this->query_closest_debug_ = b; }
433 #else
set_query_closest_debug(bool)434   void set_query_closest_debug(bool) {}
435 #endif
436 
437  private:
438   // Container holding typed face instances.
439   rgtl_sqt_objects_faces<D, (D<<1)-1> faces_container_;
440 
441   // Array of face instance pointers to allow random access to face
442   // implementations.
443   rgtl_sqt_objects_face_base<D>* faces_[(D<<1)];
444 
445   // Reference to set of objects held in spatial structure.
446   object_array_type const& object_array_;
447 
448   // Keep track of objects visited on a per-query basis.
449   rgtl_object_once object_once_;
450 
451   // The maximum subdivision level.
452   int max_level_;
453 
454   // The maximum number of objects per leaf.
455   int max_per_leaf_;
456 
457   // The guard location of the star-shaped region.
458   vnl_vector_fixed<double,D> origin_;
459 
460   friend class rgtl_sqt_objects_query_closest<D>;
461 
462 #ifdef RGTL_SQT_OBJECTS_DEBUG_QUERY
463  public:
464   // Enable closest point query output only after the distance
465   // transform has finished.
466   bool query_closest_debug_;
467 #endif
468 
469   friend class rgtl_serialize_access;
470   template <class Serializer>
serialize(Serializer & sr)471   void serialize(Serializer& sr)
472   {
473     sr & faces_container_;
474     sr & object_once_;
475     sr & max_level_;
476     sr & max_per_leaf_;
477     sr & origin_;
478   }
479 };
480 
481 //----------------------------------------------------------------------------
482 template <unsigned int D>
483 rgtl_sqt_objects_internal<D>
rgtl_sqt_objects_internal(object_array_type const & original_objs)484 ::rgtl_sqt_objects_internal(object_array_type const& original_objs):
485   faces_container_(*this, faces_),
486   object_array_(original_objs),
487   object_once_(),
488   max_level_(0), max_per_leaf_(0)
489 {
490 }
491 
492 //----------------------------------------------------------------------------
493 template <unsigned int D>
build(sqt_object_array_type const & objs,double const origin[D],int ml,int mpl)494 void rgtl_sqt_objects_internal<D>::build(sqt_object_array_type const& objs,
495                                          double const origin[D],
496                                          int ml, int mpl)
497 {
498   assert(&this->object_array_ == &objs.original());
499   this->object_once_.set_number_of_objects(
500     this->object_array_.number_of_objects());
501   this->max_level_ = ml;
502   this->max_per_leaf_ = mpl;
503 
504 #ifdef RGTL_SQT_OBJECTS_DEBUG_QUERY
505   this->query_closest_debug_ = false;
506 #endif
507 
508   for (unsigned int a=0; a < D; ++a)
509   {
510     this->origin_[a] = origin[a];
511   }
512 
513   int n = this->number_of_objects();
514   std::vector<int> ids(n);
515   for (int i=0; i < n; ++i)
516   {
517     ids[i] = i;
518   }
519 
520   for (unsigned int i=0; i < (D<<1); ++i)
521   {
522     sqt_object_set_ptr soa(objs.new_set(this->origin_.data_block(), i));
523     this->face(i).build(soa);
524   }
525 }
526 
527 //----------------------------------------------------------------------------
528 template <unsigned int D>
529 bool
query_ray(double const d[D],double x[D],double * s) const530 rgtl_sqt_objects_internal<D>::query_ray(double const d[D],
531                                         double x[D], double* s) const
532 {
533   unsigned int f = rgtl_sqt_space_base<D>::direction_to_face(d);
534   return this->face(f).query_ray(d, x, s);
535 }
536 
537 //----------------------------------------------------------------------------
538 template <unsigned int D>
539 class rgtl_sqt_objects_query_closest
540 {
541  public:
542   typedef rgtl_sqt_objects_internal<D> internal_type;
rgtl_sqt_objects_query_closest(internal_type const & intern,double const p[D],int k,double bound_squared)543   rgtl_sqt_objects_query_closest(internal_type const& intern,
544                                  double const p[D], int k,
545                                  double bound_squared)
546   : internal_(intern), best_(k)
547   {
548 #ifdef RGTL_SQT_OBJECTS_DEBUG_QUERY
549     this->checked_count_ = 0;
550 #endif
551     this->center_depth_squared_ = 0;
552     for (unsigned int a=0; a < D; ++a)
553     {
554       this->center_direction_[a] = p[a] - this->internal_.origin(a);
555       this->center_depth_squared_ +=
556         this->center_direction_[a]*this->center_direction_[a];
557     }
558     this->center_face_ =
559       rgtl_sqt_space_base<D>::direction_to_face(this->center_direction_);
560     this->internal_.face(this->center_face_).direction_to_parameters(
561       this->center_direction_, this->center_parameters_);
562     this->center_depth_ = std::sqrt(this->center_depth_squared_);
563     this->set_bound(bound_squared);
564 #ifdef RGTL_SQT_OBJECTS_DEBUG_QUERY
565     if (this->internal_.query_closest_debug_)
566     {
567       std::cout << "Querying point (";
568       const char* sep = "";
569       for (unsigned int a=0; a < D; ++a)
570       {
571         std::cout << sep << p[a];
572         sep = ", ";
573       }
574       std::cout << ") with initial bound " << this->bound_ << std::endl;
575     }
576 #endif
577   }
578 
579   void check_object(double const p[D], int k, int id);
580   int get_result(int k, int* ids, double* squared_distances, double* points);
581 
582   // Entry in the list of closest objects.
583   struct closest_object_entry
584   {
closest_object_entryrgtl_sqt_objects_query_closest::closest_object_entry585     closest_object_entry(): id(-1), distance_squared(-1) {}
closest_object_entryrgtl_sqt_objects_query_closest::closest_object_entry586     closest_object_entry(int idx, double d2, double q[D])
587     : id(idx), distance_squared(d2)
588     {
589       for (unsigned int a=0; a < D; ++a)
590       {
591         this->point[a] = q[a];
592       }
593     }
594     int id;
595     double distance_squared;
596     double point[D];
597 
operator <rgtl_sqt_objects_query_closest::closest_object_entry598     bool operator<(closest_object_entry const& that)
599     {
600       return this->distance_squared >= 0 &&
601              that.distance_squared  >= 0 &&
602              this->distance_squared < that.distance_squared;
603     }
604   };
605 
606   void update_bound(double bound);
607   void set_bound(double bound);
608 
609   // Compute the squared distance between two points.
compute_distance_squared(double const p[D],double const q[D])610   static double compute_distance_squared(double const p[D],
611                                          double const q[D])
612   {
613     double d = 0.0;
614     for (unsigned int a=0; a < D; ++a)
615     {
616       double da = p[a]-q[a];
617       d += da*da;
618     }
619     return d;
620   }
621 
622   // Compute the distance between two points.
compute_distance(double const p[D],double const q[D])623   static double compute_distance(double const p[D],
624                                  double const q[D])
625   {
626     return std::sqrt(compute_distance_squared(p, q));
627   }
628 
629   // The internal sqt objects representation.
630   internal_type const& internal_;
631 
632   // Keep a sorted list of the best k squared distances.  Use -1 to
633   // indicate no object yet found.
634   std::vector<closest_object_entry> best_;
635 
636   // Keep track of the current squared distance bound.
637   double bound_;
638 
639   // The parameters of the query point direction.
640   unsigned int center_face_;
641   double center_parameters_[D-1];
642 
643   // Keep track of the current bounding sphere.
644   double center_depth_;
645   double center_depth_squared_;
646   double center_direction_[D];
647   double radius_;
648 
649 #ifdef RGTL_SQT_OBJECTS_DEBUG_QUERY
650   // Keep track of the number of object queries made.
651   int checked_count_;
652 #endif
653 };
654 
655 //----------------------------------------------------------------------------
656 template <unsigned int D>
657 void
658 rgtl_sqt_objects_query_closest<D>
check_object(double const p[D],int k,int id)659 ::check_object(double const p[D], int k, int id)
660 {
661 #ifdef RGTL_SQT_OBJECTS_DEBUG_QUERY
662   ++this->checked_count_;
663   if (this->internal_.query_closest_debug_)
664   {
665     std::cout << "  checking object id " << id << std::endl;
666   }
667 #endif
668   // Get the squared distance to this object and use it only
669   // if it is smaller than the current distance bound.
670   double q[D];
671   double distance_squared;
672   if (this->internal_.object_closest_point(id, p, q, this->bound_) &&
673       (distance_squared = this->compute_distance_squared(p, q),
674        distance_squared <= this->bound_))
675   {
676     // Insert this object into our sorted list of k objects.
677     std::vector<closest_object_entry>& best = this->best_;
678     closest_object_entry obj(id, distance_squared, q);
679     for (int j=0; j < k && obj.distance_squared >= 0; ++j)
680     {
681       if (best[j].distance_squared < 0 || obj < best[j])
682       {
683         std::swap(obj, best[j]);
684       }
685     }
686 
687     // Update the current bounding sphere radius.
688     this->update_bound(best[k-1].distance_squared);
689   }
690 }
691 
692 //----------------------------------------------------------------------------
693 template <unsigned int D>
694 int
695 rgtl_sqt_objects_query_closest<D>
get_result(int k,int * ids,double * squared_distances,double * points)696 ::get_result(int k, int* ids, double* squared_distances, double* points)
697 {
698 #ifdef RGTL_SQT_OBJECTS_DEBUG_QUERY
699   if (this->internal_.query_closest_debug_)
700   {
701     std::cout << " Checked " << this->checked_count_
702              << " of " << this->internal_.number_of_objects()
703              << " objects." << std::endl;
704   }
705 #endif
706   // Copy the final object id list to the output.
707   std::vector<closest_object_entry>& best = this->best_;
708   for (int i=0; i < k; ++i)
709   {
710     if (best[i].distance_squared >= 0)
711     {
712 #ifdef RGTL_SQT_OBJECTS_DEBUG_QUERY
713       if (this->internal_.query_closest_debug_)
714       {
715         std::cout << i
716                  << ": id " << best[i].id
717                  << ", d  " << std::sqrt(best[i].distance_squared) << std::endl;
718       }
719 #endif
720       if (ids)
721       {
722         ids[i] = best[i].id;
723       }
724       if (squared_distances)
725       {
726         squared_distances[i] = best[i].distance_squared;
727       }
728       if (points)
729       {
730         for (unsigned int a=0; a < D; ++a)
731         {
732           points[i*D+a] = best[i].point[a];
733         }
734       }
735     }
736     else
737     {
738       return i;
739     }
740   }
741   return k;
742 }
743 
744 //----------------------------------------------------------------------------
745 template <unsigned int D>
746 void
747 rgtl_sqt_objects_query_closest<D>
set_bound(double bound)748 ::set_bound(double bound)
749 {
750   this->bound_ = bound;
751   this->radius_ = std::sqrt(bound);
752 }
753 
754 //----------------------------------------------------------------------------
755 template <unsigned int D>
756 void
757 rgtl_sqt_objects_query_closest<D>
update_bound(double bound)758 ::update_bound(double bound)
759 {
760   if (bound >= 0 && bound < this->bound_)
761   {
762     this->set_bound(bound);
763 #ifdef RGTL_SQT_OBJECTS_DEBUG_QUERY
764     if (this->internal_.query_closest_debug_)
765     {
766       std::cout << " Reduced bound to " << this->bound_ << std::endl;
767     }
768 #endif
769   }
770 }
771 
772 //----------------------------------------------------------------------------
773 template <unsigned int D, unsigned int Face>
774 class rgtl_sqt_objects_query_closest_face
775 {
776  public:
777   typedef rgtl_sqt_objects_face<D, Face> face_type;
778   typedef rgtl_sqt_objects_internal<D> internal_type;
779   typedef rgtl_sqt_objects_query_closest<D> qc_type;
780   typedef typename face_type::cell_bounds_type cell_bounds_type;
781   typedef typename face_type::cell_location_type cell_location_type;
782   typedef typename face_type::cell_index_type cell_index_type;
783   typedef typename face_type::child_index_type child_index_type;
784   typedef typename face_type::leaf_data_type leaf_data_type;
785   typedef typename face_type::node_data_type node_data_type;
786   typedef rgtl_sqt_objects_cell_data<D> cell_data_type;
787   typedef typename leaf_data_type::cone_bounds_type cone_bounds_type;
788 
rgtl_sqt_objects_query_closest_face(face_type const & face,qc_type & qc)789   rgtl_sqt_objects_query_closest_face(face_type const& face, qc_type& qc):
790     internal_(qc.internal_), face_(face), qc_(qc) {}
791 
query(double const p[D],int k,double const u[D-1])792   void query(double const p[D], int k, double const u[D-1])
793   {
794     // Recursively visit the tree starting at the root.
795     this->query_impl(cell_location_type(Face), cell_index_type(), p, k, u);
796   }
797 
798   void query_impl(cell_location_type const& cell,
799                   cell_index_type cell_index,
800                   double const p[D], int k, double const u[D-1]);
801 
802   double compute_disc_nearest(double query_distance,
803                               double query_angle, double query_depth,
804                               double cone_angle, double clip_depth) const;
805   bool disjoint(cell_data_type const* cell_data,
806                 double& nearest_squared) const;
807 
dot(cone_bounds_type const u[D],double const v[D])808   static double dot(cone_bounds_type const u[D], double const v[D])
809   {
810     double d = 0;
811     for (unsigned int a=0; a < D; ++a)
812     {
813       d += u[a]*v[a];
814     }
815     return d;
816   }
817 
818  private:
819   internal_type const& internal_;
820   face_type const& face_;
821   qc_type& qc_;
822 };
823 
824 //----------------------------------------------------------------------------
825 template <unsigned int D, unsigned int Face>
826 void
827 rgtl_sqt_objects_query_closest_face<D, Face>
query_impl(cell_location_type const & cell,cell_index_type cell_index,double const p[D],int k,double const u[D-1])828 ::query_impl(cell_location_type const& cell, cell_index_type cell_index,
829              double const p[D], int k, double const u[D-1])
830 {
831 #ifdef RGTL_SQT_OBJECTS_DEBUG_QUERY
832   if (this->internal_.query_closest_debug_)
833   {
834     std::cout << "Considering cell " << cell << std::endl;
835   }
836 #endif
837 
838   if (this->face_.tree().has_children(cell_index))
839   {
840     // Perform a fast-reject test if the current bounding sphere does
841     // not intersect the cell bounding cone.
842     double nearest_squared;
843     if (node_data_type const* nd =
844         this->face_.tree().get_node_data(cell_index))
845     {
846       if (this->disjoint(nd, nearest_squared))
847       {
848 #ifdef RGTL_SQT_OBJECTS_DEBUG_QUERY
849         if (this->internal_.query_closest_debug_)
850         {
851           std::cout << " node is disjoint" << std::endl;
852         }
853 #endif
854         return;
855       }
856     }
857     else
858     {
859       std::abort();
860     }
861 
862     // This is a node.  Compute the child containing the ray, if any.
863     // Use it to order child visitation to visit cells closer to the
864     // query point first.
865     unsigned int child_xor = 0;
866     if (u)
867     {
868       cell_bounds_type upper(cell.get_child(child_index_type((1<<(D-1))-1)));
869       for (unsigned int j=0; j < D-1; ++j)
870       {
871         if (u[j] >= upper.origin(j))
872         {
873           child_xor |= (1<<j);
874         }
875       }
876     }
877 
878     // Recursively query each child.
879     for (unsigned int i = 0;
880          i < (1<<(D-1)) && this->qc_.bound_ >= nearest_squared; ++i)
881     {
882       child_index_type child_index(i^child_xor);
883       this->query_impl(cell.get_child(child_index),
884                        this->face_.tree().get_child(cell_index,
885                                                     child_index),
886                        p, k, u);
887     }
888   }
889   else if (leaf_data_type const* ld =
890            this->face_.tree().get_leaf_data(cell_index))
891   {
892     // Perform a fast-reject test if the current bounding sphere does
893     // not intersect the cell bounding cone.
894     double nearest_squared;
895     if (this->disjoint(ld, nearest_squared))
896     {
897 #ifdef RGTL_SQT_OBJECTS_DEBUG_QUERY
898       if (this->internal_.query_closest_debug_)
899       {
900         std::cout << " leaf is disjoint" << std::endl;
901       }
902 #endif
903       return;
904     }
905 
906 #ifdef RGTL_SQT_OBJECTS_DEBUG_QUERY
907     if (this->internal_.query_closest_debug_)
908     {
909       if (ld->index_begin < ld->index_end)
910       {
911         std::cout << " checking objects" << std::endl;
912       }
913       else
914       {
915         std::cout << " no objects" << std::endl;
916       }
917     }
918 #endif
919 
920     // Test the objects in this leaf.
921     typedef typename leaf_data_type::index_type index_type;
922     for (index_type i=ld->index_begin;
923          i != ld->index_end && this->qc_.bound_ >= nearest_squared; ++i)
924     {
925       int id = this->face_.object_ids_[i];
926       if (this->internal_.visit_once(id))
927       {
928         this->qc_.check_object(p, k, id);
929       }
930     }
931   }
932 }
933 
934 //----------------------------------------------------------------------------
935 template <unsigned int D, unsigned int Face>
936 double
937 rgtl_sqt_objects_query_closest_face<D, Face>
compute_disc_nearest(double query_distance,double query_angle,double query_depth,double cone_angle,double clip_depth) const938 ::compute_disc_nearest(double query_distance,
939                        double query_angle, double query_depth,
940                        double cone_angle, double clip_depth) const
941 {
942   // The disc can be formed by intersecting a cylinder and the clip
943   // plane.  If the query point is outside the cylinder it is closest
944   // to the disc boundary.  Otherwise it is closest to the disc
945   // interior.
946   double query_r = std::sin(query_angle)*query_distance;
947   double cylinder_r = std::tan(cone_angle)*clip_depth;
948   double distance_to_plane = query_depth - clip_depth;
949   double distance_squared = distance_to_plane*distance_to_plane;
950   if (query_r > cylinder_r)
951   {
952     // Query point is closest to the disc boundary.
953     double distance_to_cylinder = query_r - cylinder_r;
954     distance_squared += distance_to_cylinder*distance_to_cylinder;
955   }
956   else
957   {
958     // Query point is closest to the disc interior.
959   }
960   return distance_squared;
961 }
962 
963 //----------------------------------------------------------------------------
964 template <unsigned int D, unsigned int Face>
965 bool
966 rgtl_sqt_objects_query_closest_face<D, Face>
disjoint(cell_data_type const * cell_data,double & nearest_squared) const967 ::disjoint(cell_data_type const* cell_data, double& nearest_squared) const
968 {
969   // Test the current bounding sphere against the cell depth range.
970   cone_bounds_type const* a = cell_data->cone_axis;
971   double const* c = this->qc_.center_direction_;
972   double a_dot_c = dot(a, c);
973   if (a_dot_c+this->qc_.radius_ < cell_data->depth_min)
974   {
975     // The bounding sphere is completely in front of the cell.
976     return true;
977   }
978   if (a_dot_c-this->qc_.radius_ > cell_data->depth_max)
979   {
980     // The bounding sphere is completely behind the cell.
981     return true;
982   }
983 
984   // Test the current bounding sphere against the cell bounding cone.
985   double const beta = cell_data->cone_angle;
986   double const theta = std::acos(a_dot_c / this->qc_.center_depth_);
987   if (theta <= beta)
988   {
989     // The sphere center is inside the cone.
990     if (a_dot_c < cell_data->depth_min)
991     {
992       // Query point is closest to near disc interior.
993       double distance_to_near_plane = cell_data->depth_min - a_dot_c;
994       nearest_squared = distance_to_near_plane*distance_to_near_plane;
995     }
996     else if (a_dot_c > cell_data->depth_max)
997     {
998       // Query point is closest to the far disc.
999       nearest_squared = this->compute_disc_nearest(this->qc_.center_depth_,
1000                                                    theta, a_dot_c, beta,
1001                                                    cell_data->depth_max);
1002     }
1003     else
1004     {
1005       // Query point is inside the clipped cone.
1006       nearest_squared = 0;
1007     }
1008 
1009     // If the distance to the nearest is at least as far as the
1010     // current bound then the sphere is disjoint.
1011     return nearest_squared >= this->qc_.bound_;
1012   }
1013 
1014   double const phi = beta + vnl_math::pi / 2;
1015   if (theta >= phi)
1016   {
1017     // The sphere center is closest to the cone tip.
1018     if (this->qc_.center_depth_squared_ > this->qc_.bound_)
1019     {
1020       // The sphere is outside the cone.
1021       return true;
1022     }
1023     else
1024     {
1025       // Query point is closest to the near disc.
1026       nearest_squared = this->compute_disc_nearest(this->qc_.center_depth_,
1027                                                    theta, a_dot_c, beta,
1028                                                    cell_data->depth_min);
1029 
1030       // If the distance to the nearest is at least as far as the
1031       // current bound then the sphere is disjoint.
1032       return nearest_squared >= this->qc_.bound_;
1033     }
1034   }
1035 
1036   // The sphere center is closest to the cone surface.
1037   double c_dot_c = this->qc_.center_depth_squared_;
1038   double distance_to_cone_surface =
1039     (std::cos(phi)*a_dot_c + std::sin(phi)*std::sqrt(c_dot_c - a_dot_c*a_dot_c));
1040   if (this->qc_.radius_ < distance_to_cone_surface)
1041   {
1042     // The sphere is outside the cone.
1043     return true;
1044   }
1045   else
1046   {
1047     // The sphere center is outside the cone.
1048     // Test against the far normal cone.
1049     double const alpha = vnl_math::pi/2 - beta;
1050     double cos_beta = std::cos(beta);
1051     double cos_beta_2 = cos_beta * cos_beta;
1052     double scale_far = cell_data->depth_max / cos_beta_2;
1053     double cos_gamma_far =
1054       ((scale_far - a_dot_c) /
1055        std::sqrt(c_dot_c - 2*scale_far*a_dot_c + scale_far*scale_far));
1056     double gamma_far = std::acos(cos_gamma_far);
1057     if (gamma_far > alpha)
1058     {
1059       // Query point is behind the far normal cone and outside the
1060       // primal cone.  It is closest to the far disc boundary.
1061       double query_r = std::sin(theta)*this->qc_.center_depth_;
1062       double cylinder_r = std::tan(beta)*cell_data->depth_max;
1063       double distance_to_far_plane = a_dot_c - cell_data->depth_max;
1064       double distance_to_far_cylinder = query_r - cylinder_r;
1065       nearest_squared =
1066         (distance_to_far_plane*distance_to_far_plane +
1067          distance_to_far_cylinder*distance_to_far_cylinder);
1068     }
1069     else
1070     {
1071       // Test against the near normal cone.
1072       double scale_near = cell_data->depth_min / cos_beta_2;
1073       double cos_gamma_near =
1074         ((scale_near - a_dot_c) /
1075          std::sqrt(c_dot_c - 2*scale_near*a_dot_c + scale_near*scale_near));
1076       double gamma_near = std::acos(cos_gamma_near);
1077       if (gamma_near < alpha)
1078       {
1079         // Query point is in front of the near normal cone and outside
1080         // the primal cone.  It is closest to the near disc.
1081         nearest_squared = this->compute_disc_nearest(this->qc_.center_depth_,
1082                                                      theta, a_dot_c, beta,
1083                                                      cell_data->depth_min);
1084       }
1085       else
1086       {
1087         // Query point is closest to the cone surface.
1088         nearest_squared = distance_to_cone_surface*distance_to_cone_surface;
1089       }
1090     }
1091 
1092     // If the distance to the nearest is at least as far as the
1093     // current bound then the sphere is disjoint.
1094     return nearest_squared >= this->qc_.bound_;
1095   }
1096 }
1097 
1098 //----------------------------------------------------------------------------
1099 template <unsigned int D>
1100 int
1101 rgtl_sqt_objects_internal<D>
query_closest(double const p[D],int k,int * ids,double * squared_distances,double * points,double bound_squared) const1102 ::query_closest(double const p[D], int k, int* ids,
1103                 double* squared_distances, double* points,
1104                 double bound_squared) const
1105 {
1106   // Setup initial query sphere radius.
1107   if (bound_squared < 0)
1108   {
1109     bound_squared = std::numeric_limits<double>::infinity();
1110   }
1111 #ifdef RGTL_SQT_OBJECTS_DEBUG_QUERY
1112   else if (this->query_closest_debug_)
1113   {
1114     std::cout << "User initial bound " << bound_squared << std::endl;
1115   }
1116 #endif
1117 
1118   // Keep track objects already tested to avoid duplicating tests.
1119   this->object_once_.reset();
1120 
1121   // Collect the results for each face.  Start with the face
1122   // containing the query point.
1123   rgtl_sqt_objects_query_closest<D> qc(*this, p, k, bound_squared);
1124   unsigned int f = qc.center_face_;
1125   this->face(f).query_closest(p, k, qc.center_parameters_, qc);
1126   for (unsigned int i=0; i < (D<<1); ++i)
1127   {
1128     if (i != f)
1129     {
1130       this->face(i).query_closest(p, k, 0, qc);
1131     }
1132   }
1133   return qc.get_result(k, ids, squared_distances, points);
1134 }
1135 
1136 //----------------------------------------------------------------------------
1137 template <unsigned int D, unsigned int Face>
1138 void
build(sqt_object_set_ptr & oa)1139 rgtl_sqt_objects_face<D, Face>::build(sqt_object_set_ptr& oa)
1140 {
1141   // Down-cast the pointer to get the per-face object set.
1142   sqt_object_set_face_ptr
1143     oaf(static_cast<rgtl_sqt_object_set_face<D, Face>*>(oa.release()));
1144 
1145   // Construct the tree starting at the root cell.
1146   this->build(cell_geometry_type(cell_location_type(Face)),
1147               cell_index_type(), oaf);
1148 }
1149 
1150 //----------------------------------------------------------------------------
1151 template <unsigned int D, unsigned int Face>
1152 void
1153 rgtl_sqt_objects_face<D, Face>
build(cell_geometry_type const & cell_geometry,cell_index_type cell_index,sqt_object_set_face_ptr & oa)1154 ::build(cell_geometry_type const& cell_geometry, cell_index_type cell_index,
1155         sqt_object_set_face_ptr& oa)
1156 {
1157   cell_location_type const& cell = cell_geometry.location();
1158 #ifdef RGTL_SQT_OBJECTS_DEBUG_BUILD2
1159   exception_stack es(cell); (void)es;
1160 #endif
1161 #ifdef RGTL_SQT_OBJECTS_DEBUG_BUILD
1162   std::cout << "Considering " << oa->number_of_objects()
1163            << " objects in cell " << cell << std::endl;
1164 #endif
1165   bool tooDeep = cell.level() >= this->internal_.max_level();
1166   bool tooMany = oa->number_of_objects() > this->internal_.max_per_leaf();
1167   if (tooMany && !tooDeep)
1168   {
1169     // Divide this cell.
1170     this->tree_.subdivide(cell_index);
1171 
1172     // Compute the bounding cone for this node.
1173     node_data_type node_data;
1174     cell_geometry.get_cone(node_data.cone_axis, node_data.cone_angle);
1175 
1176     // Compute the bounding depth range for this node.
1177     oa->get_depth_range(node_data.cone_axis,
1178                         node_data.depth_min, node_data.depth_max);
1179 
1180     // Store data in the node.
1181     this->tree_.set_node_data(cell_index, &node_data);
1182 
1183     // Distribute objects into children.
1184     sqt_object_set_face_ptr children[1<<(D-1)];
1185     oa->split(cell_geometry, children);
1186 
1187     // Erase memory used by the object array for this cell.
1188     oa.reset(0);
1189 
1190     // Compute the child cell geometries.
1191     typename cell_geometry_type::children_type child_geometry(cell_geometry);
1192 
1193     // Build the children recursively.
1194     for (child_index_type i(0); i < (1<<(D-1)); ++i)
1195     {
1196       this->build(child_geometry[i],
1197                   this->tree_.get_child(cell_index, i),
1198                   children[i]);
1199     }
1200   }
1201   else if (oa->number_of_objects() > 0)
1202   {
1203     // We will not divide this cell further.
1204     // Store the objects for this cell.
1205 #ifdef RGTL_SQT_OBJECTS_DEBUG_BUILD
1206     std::cout << "Storing " << oa->number_of_objects() << " objects in cell "
1207              << cell << std::endl;
1208 #endif
1209     typedef typename leaf_data_type::index_type index_type;
1210     index_type index_begin = index_type(this->object_ids_.size());
1211     for (int i=0; i < oa->number_of_objects(); ++i)
1212     {
1213       this->object_ids_.push_back(oa->original_id(i));
1214     }
1215     index_type index_end = index_type(this->object_ids_.size());
1216     leaf_data_type leaf_data(index_begin, index_end);
1217 
1218     // Compute the bounding cone for this leaf.
1219     cell_geometry.get_cone(leaf_data.cone_axis, leaf_data.cone_angle);
1220 
1221     // Compute the bounding depth range for this leaf.
1222     oa->get_depth_range(leaf_data.cone_axis,
1223                         leaf_data.depth_min, leaf_data.depth_max);
1224 
1225     // Store the data in the leaf.
1226     this->tree_.set_leaf_data(cell_index, &leaf_data);
1227   }
1228 }
1229 
1230 //----------------------------------------------------------------------------
1231 template <unsigned int D, unsigned int Face>
1232 bool
query_ray(double const d[D],double x[D],double * s) const1233 rgtl_sqt_objects_face<D, Face>::query_ray(double const d[D],
1234                                           double x[D], double* s) const
1235 {
1236   double u[D-1];
1237   space::direction_to_parameters(d, u);
1238   return this->query_ray(cell_location_type(Face), cell_index_type(),
1239                          u, d, x, s);
1240 }
1241 
1242 //----------------------------------------------------------------------------
1243 template <unsigned int D, unsigned int Face>
1244 bool
query_ray(cell_location_type const & cell,cell_index_type cell_index,double const u[D-1],double const d[D],double x[D],double * s) const1245 rgtl_sqt_objects_face<D, Face>::query_ray(cell_location_type const& cell,
1246                                           cell_index_type cell_index,
1247                                           double const u[D-1],
1248                                           double const d[D],
1249                                           double x[D],
1250                                           double* s) const
1251 {
1252   if (this->tree_.has_children(cell_index))
1253   {
1254     // This is a node.  Compute the child containing the ray.
1255     child_index_type child_index(0);
1256     cell_bounds_type upper(cell.get_child(child_index_type((1<<(D-1))-1)));
1257     for (unsigned int j=0; j < D-1; ++j)
1258     {
1259       if (u[j] >= upper.origin(j))
1260       {
1261         child_index |= (1<<j);
1262       }
1263     }
1264 
1265     // Recurse into the chosen child.
1266     return this->query_ray(cell.get_child(child_index),
1267                            this->tree_.get_child(cell_index, child_index),
1268                            u, d, x, s);
1269   }
1270   else if (leaf_data_type const* ld = this->tree_.get_leaf_data(cell_index))
1271   {
1272     // Test the objects in this leaf.
1273     bool found = false;
1274     double min_s = std::numeric_limits<double>::infinity();
1275     typedef typename leaf_data_type::index_type index_type;
1276     for (index_type i=ld->index_begin; i != ld->index_end; ++i)
1277     {
1278       int id = this->object_ids_[i];
1279       double cur_x[D];
1280       double cur_s;
1281       if (this->query_ray(id, d, cur_x, &cur_s))
1282       {
1283         found = true;
1284         if (cur_s < min_s)
1285         {
1286           min_s = cur_s;
1287           if (x)
1288           {
1289             for (unsigned int a=0; a < D; ++a)
1290             {
1291               x[a] = cur_x[a];
1292             }
1293           }
1294           if (s)
1295           {
1296             *s = min_s;
1297           }
1298         }
1299       }
1300     }
1301     return found;
1302   }
1303   return false;
1304 }
1305 
1306 //----------------------------------------------------------------------------
1307 template <unsigned int D, unsigned int Face>
1308 bool
query_ray(int id,double const d[D],double x[D],double * s) const1309 rgtl_sqt_objects_face<D, Face>::query_ray(int id,
1310                                           double const d[D],
1311                                           double x[D],
1312                                           double* s) const
1313 {
1314   return
1315     this->object_array().object_intersects_ray(id,
1316                                                this->origin().data_block(),
1317                                                d, x, s);
1318 }
1319 
1320 //----------------------------------------------------------------------------
1321 template <unsigned int D, unsigned int Face>
1322 void
1323 rgtl_sqt_objects_face<D, Face>
query_closest(double const p[D],int k,double const u[D-1],rgtl_sqt_objects_query_closest<D> & qc) const1324 ::query_closest(double const p[D], int k, double const u[D-1],
1325                 rgtl_sqt_objects_query_closest<D>& qc) const
1326 {
1327   rgtl_sqt_objects_query_closest_face<D, Face> qcf(*this, qc);
1328   qcf.query(p, k, u);
1329 }
1330 
1331 //----------------------------------------------------------------------------
1332 template <unsigned int D>
rgtl_sqt_objects(object_array_type const & oa)1333 rgtl_sqt_objects<D>::rgtl_sqt_objects(object_array_type const& oa):
1334   internal_(new rgtl_sqt_objects_internal<D>(oa))
1335 {
1336 }
1337 
1338 //----------------------------------------------------------------------------
1339 template <unsigned int D>
rgtl_sqt_objects(sqt_object_array_type const & soa,double const origin[D],int ml,int mpl)1340 rgtl_sqt_objects<D>::rgtl_sqt_objects(sqt_object_array_type const& soa,
1341                                       double const origin[D],
1342                                       int ml, int mpl):
1343   internal_(new rgtl_sqt_objects_internal<D>(soa.original()))
1344 {
1345   this->build(soa, origin, ml, mpl);
1346 }
1347 
1348 //----------------------------------------------------------------------------
1349 template <unsigned int D>
~rgtl_sqt_objects()1350 rgtl_sqt_objects<D>::~rgtl_sqt_objects()
1351 {
1352 }
1353 
1354 //----------------------------------------------------------------------------
1355 template <unsigned int D>
build(sqt_object_array_type const & soa,double const origin[D],int ml,int mpl)1356 void rgtl_sqt_objects<D>::build(sqt_object_array_type const& soa,
1357                                 double const origin[D],
1358                                 int ml, int mpl)
1359 {
1360   this->internal_->build(soa, origin, ml, mpl);
1361 }
1362 
1363 //----------------------------------------------------------------------------
1364 template <unsigned int D>
1365 bool
query_ray(double const d[D],double x[D],double * s) const1366 rgtl_sqt_objects<D>::query_ray(double const d[D],
1367                                double x[D], double* s) const
1368 {
1369   return this->internal_->query_ray(d, x, s);
1370 }
1371 
1372 //----------------------------------------------------------------------------
1373 template <unsigned int D>
1374 int
query_closest(double const p[D],int k,int * ids,double * squared_distances,double * points,double bound_squared) const1375 rgtl_sqt_objects<D>::query_closest(double const p[D], int k, int* ids,
1376                                    double* squared_distances, double* points,
1377                                    double bound_squared) const
1378 {
1379   return this->internal_->query_closest(p, k, ids, squared_distances, points,
1380                                         bound_squared);
1381 }
1382 
1383 //----------------------------------------------------------------------------
1384 template <unsigned int D>
origin(unsigned int a) const1385 double rgtl_sqt_objects<D>::origin(unsigned int a) const
1386 {
1387   assert(a < D);
1388   return this->internal_->origin(a);
1389 }
1390 
1391 //----------------------------------------------------------------------------
1392 template <unsigned int D>
origin() const1393 vnl_vector_fixed<double,D> const& rgtl_sqt_objects<D>::origin() const
1394 {
1395   return this->internal_->origin();
1396 }
1397 
1398 //----------------------------------------------------------------------------
1399 template <unsigned int D>
compute_bounds(double bounds[D][2]) const1400 void rgtl_sqt_objects<D>::compute_bounds(double bounds[D][2]) const
1401 {
1402   // Start with the bounds of the objects.
1403   this->internal_->object_array().compute_bounds(bounds);
1404 
1405   // Update the bounds to contain the origin.
1406   vnl_vector_fixed<double,D> const& p = this->origin();
1407   for (unsigned int a=0; a < D; ++a)
1408   {
1409     if (p[a] < bounds[a][0])
1410     {
1411       bounds[a][0] = p[a];
1412     }
1413     if (p[a] > bounds[a][1])
1414     {
1415       bounds[a][1] = p[a];
1416     }
1417   }
1418 }
1419 
1420 //----------------------------------------------------------------------------
1421 template <unsigned int D>
1422 bool
1423 rgtl_sqt_objects<D>
has_children(unsigned int face,cell_index_type cell_index) const1424 ::has_children(unsigned int face, cell_index_type cell_index) const
1425 {
1426   assert(face < (D<<1));
1427   return this->internal_->face(face).tree().has_children(cell_index);
1428 }
1429 
1430 //----------------------------------------------------------------------------
1431 template <unsigned int D>
1432 typename rgtl_sqt_objects<D>::cell_index_type
1433 rgtl_sqt_objects<D>
get_child(unsigned int face,cell_index_type cell_index,child_index_type child) const1434 ::get_child(unsigned int face, cell_index_type cell_index,
1435             child_index_type child) const
1436 {
1437   assert(face < (D<<1));
1438   return this->internal_->face(face).tree().get_child(cell_index, child);
1439 }
1440 
1441 //----------------------------------------------------------------------------
1442 template <unsigned int D>
1443 bool
1444 rgtl_sqt_objects<D>
get_depth_range(unsigned int face,cell_index_type cell_index,double & depth_min,double & depth_max) const1445 ::get_depth_range(unsigned int face, cell_index_type cell_index,
1446                   double& depth_min, double& depth_max) const
1447 {
1448   assert(face < (D<<1));
1449   typedef rgtl_sqt_objects_face_base<D> face_base;
1450   typedef typename face_base::tree_type tree_type;
1451   typedef typename face_base::node_data_type node_data_type;
1452   typedef typename face_base::leaf_data_type leaf_data_type;
1453   tree_type const& tree = this->internal_->face(face).tree();
1454   if (tree.has_children(cell_index))
1455   {
1456     if (node_data_type const* nd = tree.get_node_data(cell_index))
1457     {
1458       depth_min = nd->depth_min;
1459       depth_max = nd->depth_max;
1460       return true;
1461     }
1462   }
1463   else
1464   {
1465     if (leaf_data_type const* ld = tree.get_leaf_data(cell_index))
1466     {
1467       depth_min = ld->depth_min;
1468       depth_max = ld->depth_max;
1469       return true;
1470     }
1471   }
1472   return false;
1473 }
1474 
1475 //----------------------------------------------------------------------------
1476 template <unsigned int D>
1477 void
1478 rgtl_sqt_objects<D>
set_query_closest_debug(bool b)1479 ::set_query_closest_debug(bool b)
1480 {
1481   this->internal_->set_query_closest_debug(b);
1482 }
1483 
1484 //----------------------------------------------------------------------------
1485 template <unsigned int D>
1486 template <class Serializer>
serialize(Serializer & sr)1487 void rgtl_sqt_objects<D>::serialize(Serializer& sr)
1488 {
1489   sr & *(this->internal_);
1490 }
1491 
1492 //----------------------------------------------------------------------------
1493 #define RGTL_SQT_OBJECTS_INSTANTIATE(D) \
1494   template class rgtl_sqt_objects_internal< D >; \
1495   template class rgtl_sqt_objects< D >; \
1496   template void rgtl_sqt_objects< D > \
1497     ::serialize<rgtl_serialize_ostream>(rgtl_serialize_ostream&); \
1498   template void rgtl_sqt_objects< D > \
1499     ::serialize<rgtl_serialize_istream>(rgtl_serialize_istream&)
1500 #define RGTL_SQT_OBJECTS_FACE_INSTANTIATE(D, Face) \
1501   template class rgtl_sqt_objects_face< D , Face >
1502 
1503 #endif
1504