test_basics.cpp
Go to the documentation of this file.
00001 #include <gtest/gtest.h>
00002 #include <cmath>
00003 
00004 #include <megatree/megatree.h>
00005 #include <megatree/allocator.h>
00006 #include <megatree/storage_factory.h>
00007 #include <megatree/node_file.h>
00008 #include <megatree/tree_functions.h>
00009 
00010 using namespace megatree;
00011 
00012 static const double point_precision = 0.001;
00013 
00014 #define EXPECT_V3_NEAR(a, b, c, v, tolerance)                                     \
00015   if (v.size() != 3)  ADD_FAILURE() << "Vector did not have 3 elements"; \
00016   else { \
00017   EXPECT_NEAR(a, v[0], tolerance); \
00018   EXPECT_NEAR(b, v[1], tolerance); \
00019   EXPECT_NEAR(c, v[2], tolerance); \
00020   }
00021 
00022 #define EXPECT_F3_NEAR(a, b, c, v, tolerance)             \
00023   EXPECT_NEAR(a, v[0], tolerance); \
00024   EXPECT_NEAR(b, v[1], tolerance); \
00025   EXPECT_NEAR(c, v[2], tolerance); 
00026 
00027 
00028 
00029 TEST(MegaTreeBasics, NodeGeometry)
00030 {
00031   double center[] = {0,0,0};
00032   NodeGeometry p(center, 10.0);
00033 
00034   NodeGeometry c = p.getChild(3);
00035   EXPECT_NEAR(5.0, c.getSize(), 1e-3);
00036   EXPECT_NEAR(-2.5, c.getCenter(0),  1e-6);
00037   EXPECT_NEAR( 2.5, c.getCenter(1),  1e-6);
00038   EXPECT_NEAR( 2.5, c.getCenter(2),  1e-6);
00039 
00040   p = NodeGeometry(center, 6386850.000000);
00041   c = p.getChild(3);
00042   EXPECT_NEAR(3193425.0, c.getSize(), 1e-3);
00043   EXPECT_NEAR(-1596712.5, c.getCenter(0),  1e-6);
00044   EXPECT_NEAR(1596712.5, c.getCenter(1),  1e-6);
00045   EXPECT_NEAR(1596712.5, c.getCenter(2),  1e-6);
00046 
00047   double new_center[] = {-1596712.500000, 1596712.500000, 1596712.500000};
00048   p = NodeGeometry(new_center, 3193425.000000);
00049   c = p.getChild(3);
00050   EXPECT_NEAR(1596712.5, c.getSize(), 1e-3);
00051   EXPECT_NEAR(-2395068.75, c.getCenter(0),  1e-6);
00052   EXPECT_NEAR(2395068.75, c.getCenter(1),  1e-6);
00053   EXPECT_NEAR(2395068.75, c.getCenter(2),  1e-6);
00054 }
00055 
00056 
00057 TEST(MegaTreeBasics, NodeGeometryInPlace)
00058 {
00059   double center[] = {0,0,0};
00060   NodeGeometry p(center, 10.0);
00061 
00062   NodeGeometry c = p;
00063   c = c.getChild(3);
00064   EXPECT_NEAR(5.0, c.getSize(), 1e-3);
00065   EXPECT_NEAR(-2.5, c.getCenter(0),  1e-6);
00066   EXPECT_NEAR(2.5, c.getCenter(1),  1e-6);
00067   EXPECT_NEAR(2.5, c.getCenter(2),  1e-6);
00068 }
00069 
00070 
00071 TEST(MegaTreeBasics, NodeGeometryPrecision_EdgesShouldAlign)
00072 {
00073   // Descends 26 levels down, once right, then always left.  The left
00074   // edge of this small box should match perfectly with the center of
00075   // the original box.
00076   double r_lo[] = {-5863017.3200000003, -2192262.1200000001, -6386851.2000000002};
00077   double r_hi[] = {6910682.6799999997, 10581437.879999999, 6386848.7999999998};
00078   NodeGeometry r(1, r_lo, r_hi);
00079 
00080   NodeGeometry child = r.getChild(7);  // Descends to the right
00081   for (size_t i = 0; i < 26; ++i)
00082   {
00083     double child_left_edge = child.getLo(0);
00084 
00085     // Note: They must be exactly equal.  If they are only
00086     // approximately equal a point can be assigned to a particular
00087     // node, but the node will think that the point is not contained
00088     // in the node.
00089     //EXPECT_EQ(r_center[0], child_left_edge) << " at level " << i;
00090     ASSERT_NEAR(r.getCenter(0), child_left_edge, 0.0) << "Descended " << (i + 1) << " times";
00091 
00092     child = child.getChild(0);  // Descends to the left
00093   }
00094 }
00095 
00096 
00097 
00098 TEST(MegaTreeBasics, Node)
00099 {
00100   std::vector<double> tree_center(3,0);
00101   Node n;
00102 
00103   for (uint8_t i=0; i<8; i++)
00104     EXPECT_FALSE(n.hasChild(i));
00105 
00106   n.setChild(0);
00107   EXPECT_TRUE(n.hasChild(0));
00108   for(uint8_t i = 1; i < 8; ++i)
00109     EXPECT_FALSE(n.hasChild(i));
00110 
00111   n.setChild(7);
00112   EXPECT_TRUE(n.hasChild(0));
00113   EXPECT_TRUE(n.hasChild(7));
00114   for(uint8_t i = 1; i < 7; ++i)
00115     EXPECT_FALSE(n.hasChild(i));
00116 }
00117 
00118 
00119 TEST(MegaTreeBasics, OctreeLevel)
00120 {
00121   EXPECT_EQ(1, IdType(1).level());
00122   EXPECT_EQ(2, IdType(010).level());
00123   EXPECT_EQ(3, IdType(0177).level());
00124   EXPECT_EQ(8, IdType(014637720).level());
00125 
00126   EXPECT_EQ(IdType(01), IdType(017).getParent());
00127   EXPECT_EQ(IdType(012747241), IdType(0127472410).getParent());
00128 
00129   EXPECT_EQ(IdType(0), IdType(1).getParent());
00130 }
00131 
00132 
00133 TEST(MegaTreeBasics, NodePoint)
00134 {
00135   double point[3], color[3];
00136   point[0] = point[1] = point[2] = color[0] = color[1] = color[2] = 0;
00137   point[0] = 0.02;
00138   color[0] = 230;
00139 
00140   double center[] = {0, 0, 0};
00141   double tree_size = 1.0;
00142   NodeGeometry ng(center, tree_size);
00143   Node n;
00144   n.setPoint(ng, point, color);
00145   
00146   double point_get[3], color_get[3];
00147   n.getPoint(ng, point_get);
00148   n.getColor(color_get);
00149   
00150   EXPECT_NEAR(point[0], point_get[0], 2.*ng.getSize()/256.);
00151   EXPECT_NEAR(point[1], point_get[1], 2.*ng.getSize()/256.);
00152   EXPECT_NEAR(point[2], point_get[2], 2.*ng.getSize()/256.);
00153 
00154   EXPECT_NEAR(color[0], color_get[0], 2.*ng.getSize()/256.);
00155   EXPECT_NEAR(color[1], color_get[1], 2.*ng.getSize()/256.);
00156   EXPECT_NEAR(color[2], color_get[2], 2.*ng.getSize()/256.);
00157 }
00158 
00159 
00160 
00161 
00162 TEST(MegaTreeBasics, SinglePointRangeQuery)
00163 {
00164   std::vector<double> tree_center(3, 0);
00165   double tree_size = 10;
00166   boost::shared_ptr<TempDir> tree_path = createTempDir("rangequery", true);
00167   boost::shared_ptr<Storage> storage(openStorage(tree_path->getPath()));
00168   MegaTree tree(storage, tree_center, tree_size, 3, 1);
00169 
00170   // Adds a single point
00171   std::vector<double> pt(3, 0);
00172   addPoint(tree, pt);
00173 
00174   // Queries a range around the point
00175   std::vector<double> range_lo(3, -1.0f), range_hi(3, 1.0f);
00176   std::vector<double> result, colors;
00177   queryRange(tree, range_lo, range_hi, point_precision, result, colors);
00178   EXPECT_V3_NEAR(0, 0, 0,  result, 2.*point_precision);
00179 
00180   // Queries a range without any points
00181   range_lo[0] = 1.0f;
00182   range_lo[1] = 1.0f;
00183   range_lo[2] = 1.0f;
00184   range_hi[0] = 4.0f;
00185   range_hi[1] = 4.0f;
00186   range_hi[2] = 4.0f;
00187   result.clear();
00188   colors.clear();
00189   queryRange(tree, range_lo, range_hi, point_precision, result, colors);
00190   EXPECT_EQ(0, result.size());
00191 }
00192 
00193 
00194 void gridTest(bool clear)
00195 {
00196   std::vector<double> tree_center(3, 10);
00197   double tree_size = 30.0;
00198   NodeGeometry ng(tree_center, tree_size);
00199 
00200   boost::shared_ptr<TempDir> tree_path(createTempDir("rangequery", true));
00201   boost::shared_ptr<Storage> storage(openStorage(tree_path->getPath()));
00202   MegaTree tree(storage, tree_center, tree_size, 4, 1);
00203 
00204   // Creates a grid of points
00205   const double STEP = 1;
00206   const size_t WIDTH = 20;
00207   std::vector<double> pt(3, 0.0f);
00208   for (size_t i = 0; i < WIDTH; ++i)
00209   {
00210     for (size_t j = 0; j < WIDTH; ++j)
00211     {
00212       for (size_t k = 0; k < WIDTH; ++k)
00213       {
00214         pt[0] = STEP * i;
00215         pt[1] = STEP * j;
00216         pt[2] = STEP * k;
00217         addPoint(tree, pt);
00218       }
00219     }
00220   }
00221 
00222   if (clear)
00223     tree.flushCache();
00224 
00225   // Checks that the correct number of points have been added.
00226   NodeHandle root;
00227   tree.getRoot(root);
00228   ASSERT_TRUE(root.getCount() > 1);  // Probably
00229   EXPECT_EQ(pow(WIDTH, 3), root.getCount());
00230 
00231   // Checks that the summarization is correct
00232   double mean = double(WIDTH - 1) / 2 * STEP;
00233   double point[3];
00234   root.getPoint(point);
00235   EXPECT_NEAR(mean, point[0], 2. * tree_size / 256.);
00236   EXPECT_NEAR(mean, point[1], 2. * tree_size / 256.);
00237   EXPECT_NEAR(mean, point[2], 2. * tree_size / 256.);
00238   tree.releaseNode(root);
00239 
00240   // Queries a box with all the points
00241   std::vector<double> range_lo(3, -1), range_hi(3, WIDTH * STEP + 1);
00242   std::vector<double> result, colors;
00243   queryRange(tree, range_lo, range_hi, point_precision, result, colors);
00244   EXPECT_EQ(pow(WIDTH, 3), result.size() / 3);
00245 
00246   // Queries for half the points
00247   range_hi[0] = WIDTH * STEP;
00248   range_hi[1] = WIDTH * STEP;
00249   range_hi[2] = (WIDTH * STEP) / 2;
00250   result.clear();
00251   colors.clear();
00252   queryRange(tree, range_lo, range_hi, point_precision, result, colors);
00253   EXPECT_EQ(pow(WIDTH, 3) / 2, result.size() / 3);
00254 
00255   // Queries for exactly 8 points
00256   range_lo[0] = 2 * STEP - 0.00001;
00257   range_lo[1] = 2 * STEP - 0.00001;
00258   range_lo[2] = 2 * STEP - 0.00001;
00259   range_hi[0] = 4 * STEP - 0.00001;
00260   range_hi[1] = 4 * STEP - 0.00001;
00261   range_hi[2] = 4 * STEP - 0.00001;
00262   result.clear();
00263   colors.clear();
00264   queryRange(tree, range_lo, range_hi, point_precision, result, colors);
00265   EXPECT_EQ(8, result.size() / 3);
00266 
00267   // Queries for a line of points along x
00268   range_lo[0] = -1000;        range_hi[0] = 1000;
00269   range_lo[1] = 5.9 * STEP;   range_hi[1] = 6.1 * STEP;
00270   range_lo[2] = 5.9 * STEP;   range_hi[2] = 6.1 * STEP;
00271   result.clear();
00272   colors.clear();
00273   queryRange(tree, range_lo, range_hi, point_precision, result, colors);
00274   EXPECT_EQ(WIDTH, result.size() / 3);
00275 }
00276 
00277 
00278 TEST(MegaTreeBasics, GridRangeQuery)
00279 {
00280   gridTest(false);
00281   gridTest(true);
00282 }
00283 
00284 TEST(MegaTreeBasics, TestDiskAccess)
00285 {
00286   std::vector<double> tree_center(3, 0);
00287   double tree_size = 1000000;
00288 
00289   boost::shared_ptr<TempDir> tree1_path(createTempDir("tree1", true));
00290   boost::shared_ptr<Storage> storage1(openStorage(tree1_path->getPath()));
00291   MegaTree tree1(storage1, tree_center, tree_size, 3, 1);
00292 
00293   boost::shared_ptr<TempDir> tree2_path(createTempDir("tree2", true));
00294   boost::shared_ptr<Storage> storage2(openStorage(tree2_path->getPath()));
00295   MegaTree tree2(storage2, tree_center, tree_size, 2, 1);
00296 
00297   // Adds a grid of points
00298   const double STEP = 1;
00299   const size_t WIDTH = 2;
00300   std::vector<double> pt(3, 0.0f);
00301   for (size_t i = 0; i < WIDTH; ++i)
00302   {
00303     for (size_t j = 0; j < WIDTH; ++j)
00304     {
00305       for (size_t k = 0; k < WIDTH; ++k)
00306       {
00307         pt[0] = STEP * i;
00308         pt[1] = STEP * j;
00309         pt[2] = STEP * k;
00310         addPoint(tree1, pt);
00311         addPoint(tree2, pt);
00312       }
00313     }
00314   }
00315 
00316   tree1.flushCache();
00317   EXPECT_TRUE(tree1 == tree2);
00318 
00319   //test to make sure we can load from disk
00320   boost::shared_ptr<Storage> storage3(openStorage(tree1_path->getPath()));
00321   MegaTree tree3(storage3, 10000, true);
00322 
00323   EXPECT_TRUE(tree1 == tree3);
00324   EXPECT_TRUE(tree2 == tree3);
00325 
00326 }
00327 
00328 TEST(MegaTreeBasics, ColorSanityCheck)
00329 {
00330   std::vector<double> tree_center(3, 0);
00331   double tree_size = 1000000;
00332 
00333   boost::shared_ptr<TempDir> tree_path(createTempDir("test_color_tree", true));
00334   boost::shared_ptr<Storage> storage(openStorage(tree_path->getPath()));
00335   MegaTree tree(storage, tree_center, tree_size, 3, 1);
00336 
00337   // Adds a point with color
00338   std::vector<double> pt(3, 0);
00339   std::vector<double> color(3, 0);
00340   color[0] = 1.0f;
00341   color[1] = 255.0f;
00342   addPoint(tree, pt, color);
00343 
00344   NodeHandle root;
00345   tree.getRoot(root);
00346   double col[3];
00347   root.getColor(col);
00348   EXPECT_NEAR(1.0, col[0], 1e-5);
00349   EXPECT_NEAR(255.0, col[1], 1e-5);
00350   tree.releaseNode(root);
00351 
00352   // Writes the tree to disk, and loads it as tree2.
00353   tree.flushCache();
00354   boost::shared_ptr<Storage> storage2(openStorage(tree_path->getPath()));
00355   MegaTree tree2(storage2, 10000, true);
00356   NodeHandle root2;
00357   tree2.getRoot(root2);
00358   root2.getColor(col);
00359   EXPECT_NEAR(1.0, col[0], 1e-5);
00360   EXPECT_NEAR(255.0, col[1], 1e-5);
00361   tree2.releaseNode(root2);
00362 }
00363 
00364 TEST(MegaTreeBasics, ColorsAggregateProperly)
00365 {
00366   std::vector<double> tree_center(3, 0);
00367   double tree_size = 100;
00368 
00369   boost::shared_ptr<TempDir> tree_path(createTempDir("test_color_tree", true));
00370   boost::shared_ptr<Storage> storage(openStorage(tree_path->getPath()));
00371   MegaTree tree(storage, tree_center, tree_size, 2, 1);
00372 
00373   // Add two points with color
00374   std::vector<double> pt(3, 0);
00375   std::vector<double> color(3, 0);
00376   color[0] = 254.0;
00377   color[1] = 254.0;
00378   color[2] = 0.0;
00379   addPoint(tree, pt, color);
00380   pt[0] = 0.1;
00381   color[0] = 0.0;
00382   color[1] = 254.0;
00383   color[2] = 254.0;
00384   addPoint(tree, pt, color);
00385 
00386   NodeHandle root;
00387   tree.getRoot(root);
00388   double col[3];
00389   root.getColor(col);
00390   EXPECT_NEAR(127.0, col[0], 1e-5);
00391   EXPECT_NEAR(254.0, col[1], 1e-5);
00392   EXPECT_NEAR(127.0, col[2], 1e-5);
00393   tree.releaseNode(root);
00394 }
00395 
00396 
00397 // Run all the tests that were declared with TEST()
00398 int main(int argc, char **argv){
00399   testing::InitGoogleTest(&argc, argv);
00400   return RUN_ALL_TESTS();
00401 }


megatree_cpp
Author(s): Stuart Glaser
autogenerated on Thu Nov 28 2013 11:30:34