void OutofcoreCloud::render (vtkRenderer* renderer) { vtkSmartPointer<vtkCamera> active_camera = renderer->GetActiveCamera (); Scene *scene = Scene::instance (); Camera *camera = scene->getCamera (active_camera); if (render_camera_ != NULL && render_camera_->getName() == camera->getName ()) { renderer->ComputeAspect (); //double *aspect = renderer->GetAspect (); int *size = renderer->GetSize (); OctreeDisk::BreadthFirstIterator breadth_first_it (*octree_); breadth_first_it.setMaxDepth(display_depth_); double frustum[24]; camera->getFrustum(frustum); Eigen::Vector3d eye = camera->getPosition(); Eigen::Matrix4d view_projection_matrix = camera->getViewProjectionMatrix(); //Eigen::Matrix4d view_projection_matrix = projection_matrix * model_view_matrix;//camera->getViewProjectionMatrix(); cloud_actors_->RemoveAllItems (); while ( *breadth_first_it !=0 ) { OctreeDiskNode *node = *breadth_first_it; Eigen::Vector3d min_bb, max_bb; node->getBoundingBox(min_bb, max_bb); // Frustum culling if (pcl::visualization::cullFrustum(frustum, min_bb, max_bb) == pcl::visualization::PCL_OUTSIDE_FRUSTUM) { breadth_first_it.skipChildVoxels(); breadth_first_it++; continue; } // Bounding box lod projection float coverage = pcl::visualization::viewScreenArea(eye, min_bb, max_bb, view_projection_matrix, size[0], size[1]); if (coverage <= lod_pixel_threshold_) { breadth_first_it.skipChildVoxels(); } // for (int i=0; i < node->getDepth(); i++) // std::cout << " "; // std::cout << coverage << "-" << pcd_file << endl;//" : " << (coverage > (size[0] * size[1])) << endl; std::string pcd_file = node->getPCDFilename ().string (); cloud_data_cache_mutex.lock(); PcdQueueItem pcd_queue_item(pcd_file, coverage); // If we can lock the queue add another item if (pcd_queue_mutex.try_lock()) { pcd_queue.push(pcd_queue_item); pcd_queue_mutex.unlock(); } if (cloud_data_cache.hasKey(pcd_file)) { //std::cout << "Has Key for: " << pcd_file << std::endl; if (cloud_actors_map_.find (pcd_file) == cloud_actors_map_.end ()) { vtkSmartPointer<vtkActor> cloud_actor = vtkSmartPointer<vtkActor>::New (); CloudDataCacheItem *cloud_data_cache_item = &cloud_data_cache.get(pcd_file); #if VTK_RENDERING_BACKEND_OPENGL_VERSION < 2 vtkSmartPointer<vtkVertexBufferObjectMapper> mapper = vtkSmartPointer<vtkVertexBufferObjectMapper>::New (); mapper->SetInput (cloud_data_cache_item->item); #else vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New (); // Usually we choose between SetInput and SetInputData based on VTK version. But OpenGL ≥ 2 automatically // means VTK version is ≥ 6.3 mapper->SetInputData (cloud_data_cache_item->item); #endif cloud_actor->SetMapper (mapper); cloud_actor->GetProperty ()->SetColor (0.0, 0.0, 1.0); cloud_actor->GetProperty ()->SetPointSize (1); cloud_actor->GetProperty ()->SetLighting (false); cloud_actors_map_[pcd_file] = cloud_actor; } if (!hasActor (cloud_actors_map_[pcd_file])) { points_loaded_ += cloud_actors_map_[pcd_file]->GetMapper ()->GetInput ()->GetNumberOfPoints (); data_loaded_ += cloud_actors_map_[pcd_file]->GetMapper ()->GetInput ()->GetActualMemorySize(); } //std::cout << "Adding Actor: " << pcd_file << std::endl; cloud_actors_->AddItem (cloud_actors_map_[pcd_file]); addActor (cloud_actors_map_[pcd_file]); } cloud_data_cache_mutex.unlock(); breadth_first_it++; } // We're done culling, notify the pcd_reader thread the queue is read pcd_queue_ready.notify_one(); std::vector<vtkActor*> actors_to_remove; { actors_to_remove.clear (); actors_->InitTraversal (); for (vtkIdType i = 0; i < actors_->GetNumberOfItems (); i++) { vtkActor* actor = actors_->GetNextActor (); if (actor != voxel_actor_.GetPointer ()) { bool actor_found = false; cloud_actors_->InitTraversal (); for (vtkIdType j = 0; j < cloud_actors_->GetNumberOfItems (); j++) { vtkActor* cloud_actor = cloud_actors_->GetNextActor (); if (actor == cloud_actor) { actor_found = true; break; } } if (!actor_found) { actors_to_remove.push_back (actor); } } } } for (size_t i = 0; i < actors_to_remove.size (); i++) { points_loaded_ -= actors_to_remove.back ()->GetMapper ()->GetInput ()->GetNumberOfPoints (); data_loaded_ -= actors_to_remove.back ()->GetMapper ()->GetInput ()->GetActualMemorySize(); removeActor (actors_to_remove.back ()); actors_to_remove.pop_back (); } } Object::render(renderer); }
int outofcorePrint (boost::filesystem::path tree_root, size_t print_depth, bool bounding_box=false, bool pcd=false, bool point_count=false, bool breadth_first=false) { std::cout << boost::filesystem::absolute (tree_root) << std::endl; OctreeDisk* octree; octree = new OctreeDisk (tree_root, true); Eigen::Vector3d min, max; octree->getBoundingBox(min, max); // Cloud bounding box PCL_INFO (" Bounding Box: <%lf, %lf, %lf> - <%lf, %lf, %lf>\n", min[0], min[1], min[2], max[0], max[1], max[2]); // Cloud depth uint64_t depth = octree->getTreeDepth (); PCL_INFO (" Depth: %ld\n", depth); if (print_depth > depth) print_depth = depth; // Cloud point counts at each level std::vector<boost::uint64_t> lodPoints = octree->getNumPointsVector (); PCL_INFO (" Points:\n"); for (boost::uint64_t i = 0; i < lodPoints.size (); i++) PCL_INFO (" %d: %d\n", i, lodPoints[i]); // Cloud voxel side length PCL_INFO(" Voxel Side Length: %d\n", octree->getVoxelSideLength ()); // Cloud voxel count std::vector<PointT, AlignedPointT> voxel_centers; octree->getOccupiedVoxelCenters(voxel_centers); PCL_INFO(" Voxel Count: %d\n", voxel_centers.size ()); // Point data for statistics std::vector<boost::uint64_t> pointsPerVoxel; ba::accumulator_set<boost::uint64_t, ba::features< ba::tag::min, ba::tag::max, ba::tag::mean, ba::tag::variance> > acc; if (!breadth_first) { OctreeDisk::DepthFirstIterator depth_first_it (*octree); while ( *depth_first_it !=nullptr ) { OctreeDiskNode *node = *depth_first_it; size_t node_depth = node->getDepth(); printDepth(node_depth); std::string metadata_relative_file = node->getMetadataFilename ().string (); boost::replace_first(metadata_relative_file, tree_root.parent_path ().string (), ""); PCL_INFO ("..%s\n", metadata_relative_file.c_str()); printDepth(node_depth); if (pcd) { std::string pcd_relative_file = node->getPCDFilename ().string (); boost::replace_first(pcd_relative_file, tree_root.parent_path ().string (), ""); PCL_INFO (" PCD: ..%s\n", pcd_relative_file.c_str()); } if (bounding_box) { Eigen::Vector3d min, max; node->getBoundingBox(min, max); printDepth(node_depth); PCL_INFO (" Bounding Box: <%lf, %lf, %lf> - <%lf, %lf, %lf>\n", min[0], min[1], min[2], max[0], max[1], max[2]); } if (point_count) { printDepth(node_depth); PCL_INFO (" Points: %lu\n", node->getDataSize()); pointsPerVoxel.push_back( node->getDataSize()); acc(node->getDataSize()); } depth_first_it++; } } else { OctreeDisk::BreadthFirstIterator breadth_first_it (*octree); breadth_first_it.setMaxDepth (static_cast<unsigned int> (print_depth)); while ( *breadth_first_it !=nullptr ) { OctreeDiskNode *node = *breadth_first_it; size_t node_depth = node->getDepth(); printDepth(node_depth); std::string metadata_relative_file = node->getMetadataFilename ().string (); boost::replace_first(metadata_relative_file, tree_root.parent_path ().string (), ""); PCL_INFO ("..%s\n", metadata_relative_file.c_str()); printDepth(node_depth); if(pcd) { std::string pcd_relative_file = node->getPCDFilename ().string (); boost::replace_first(pcd_relative_file, tree_root.parent_path ().string (), ""); PCL_INFO (" PCD: ..%s\n", pcd_relative_file.c_str()); } if (bounding_box) { Eigen::Vector3d min, max; node->getBoundingBox(min, max); printDepth(node_depth); PCL_INFO (" Bounding Box: <%lf, %lf, %lf> - <%lf, %lf, %lf>\n", min[0], min[1], min[2], max[0], max[1], max[2]); } if (point_count) { printDepth(node_depth); PCL_INFO (" Points: %lu\n", node->getDataSize()); pointsPerVoxel.push_back( node->getDataSize()); acc(node->getDataSize()); } breadth_first_it++; } } if(point_count) { PCL_INFO("Points per Voxel:\n"); PCL_INFO("Min: %u, Max: %u, Mean: %f, StdDev %f\n", ba::min(acc), ba::max(acc), ba::mean(acc), sqrt(ba::variance(acc))); } return 0; }