Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用全局集合为预构建的八叉树数据保存Boost shared_ptr:s,用于快速点云光线投射操作_C++_Multithreading_Boost_Point Cloud Library - Fatal编程技术网

C++ 使用全局集合为预构建的八叉树数据保存Boost shared_ptr:s,用于快速点云光线投射操作

C++ 使用全局集合为预构建的八叉树数据保存Boost shared_ptr:s,用于快速点云光线投射操作,c++,multithreading,boost,point-cloud-library,C++,Multithreading,Boost,Point Cloud Library,我正在做一些测试,为虚拟现实点云查看器创建一个光线投射系统。基础是由Unity Engine制作的,但是导入、从磁盘读取和渲染点云数据是独立的,作为Unity和GPU着色器代码的dll插件 点云数据被划分为独立的块,当用户在虚拟现实场景中移动时,这些块被动态加载和卸载。我通过创建一个全局std::unordered_映射进行了第一次测试,其中key是加载块的数据文件名,value是Boost shared_ptr。我将粘贴下面的代码,它应该很容易理解 下面的代码可以完美地处理一个数据块,但是对于

我正在做一些测试,为虚拟现实点云查看器创建一个光线投射系统。基础是由Unity Engine制作的,但是导入、从磁盘读取和渲染点云数据是独立的,作为Unity和GPU着色器代码的dll插件

点云数据被划分为独立的块,当用户在虚拟现实场景中移动时,这些块被动态加载和卸载。我通过创建一个全局std::unordered_映射进行了第一次测试,其中key是加载块的数据文件名,value是Boost shared_ptr。我将粘贴下面的代码,它应该很容易理解

下面的代码可以完美地处理一个数据块,但是对于更多的数据块,我似乎可以得到一个点的索引,然后通过索引读取云数据本身来检查点值,这实际上使用了一个随机块数据的正确结果索引。当我用VR控制器激光指针扫视时,我在场景中看到我的视觉建议在另一个块的区域,然后跳到另一个块的区域,依此类推。这可能是线程问题,因为findInOcTree是从Unity主线程调用的,而createOcTree和releaseOcTree是从异步磁盘读取线程调用的。但我完全不确定使用全局集合进行共享\u ptr:s这种方式是否没有问题

所以,欢迎大家提出我应该朝哪个方向走的想法。是否有更好的并发收集选项可以替代std::unordered_map,或者我应该使用某种手动锁定技术?还有其他我现在看不到的危险吗

#define EXPORT_API __declspec(dllexport)

#include <vector>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/octree/octree.h>


// Link following functions C-style (required for plugins)
extern "C"
{   
    pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGBA>);

    /// Two different ways to say the same thing
    std::unordered_map<std::string, pcl::octree::OctreePointCloudSearch<pcl::PointXYZRGBA>::Ptr> ocTreeMap;
    //std::unordered_map<std::string, boost::shared_ptr<pcl::octree::OctreePointCloudSearch<pcl::PointXYZRGBA>>> ocTreeMap;

    // using this makes no difference with many blocks; one block works with and without
    std::unordered_map<string, pcl::PointCloud<pcl::PointXYZRGBA>::Ptr> cloudMap;

    EXPORT_API bool createOcTree(char *blockName)
    {
        if (ocTreeMap.find(blockName) == ocTreeMap.end())
        {
            pcl::octree::OctreePointCloudSearch<pcl::PointXYZRGBA>::Ptr octree(new pcl::octree::OctreePointCloudSearch<pcl::PointXYZRGBA>(0.0025f));

            octree->setInputCloud(cloud);
            octree->addPointsFromInputCloud();

            /// using this makes no difference with many blocks; one block works with and without
            if (cloudMap.find(blockName) != cloudMap.end())
            {
                cloudMap.erase(blockName);
            }
            cloudMap[blockName] = cloud;
            ocTreeMap[blockName] = octree;

            return true;
        }
        return false;
    }


    EXPORT_API bool releaseOcTree(char *blockName)
    {
        if (ocTreeMap.erase(blockName) == 0)
        {
            return false;
        }
        else
        {
            /// using this makes no difference with many blocks; one block works with and without
            cloudMap.erase(blockName);  

            return true;
        }
    }


    EXPORT_API bool findInOcTree(char *filePath, float originX, float originY, float originZ, float directionX, float directionY, float directionZ, float* hitX, float* hitY, float* hitZ)
    {
        Eigen::Vector3f origin(originX, originY, originZ);
        Eigen::Vector3f direction(directionX, directionY, directionZ);
        std::vector<int> k_indices;

        boost::shared_ptr<pcl::octree::OctreePointCloudSearch<pcl::PointXYZRGBA>> octree = ocTreeMap[filePath];

        /// using this makes no difference with many blocks; one block works with and without
        boost::shared_ptr<pcl::PointCloud<pcl::PointXYZRGBA>> pCloud = cloudMap[filePath];

        octree->getIntersectedVoxelIndices(origin, direction, k_indices, 1);

        if (!k_indices.empty())
        {
            *hitX = pCloud->points[k_indices[0]].x;
            *hitY = pCloud->points[k_indices[0]].y;
            *hitZ = pCloud->points[k_indices[0]].z;

            return true;
        }
        return false;
    }
}
#定义导出(API)(dllexport)
#包括
#包括
#包括
#包括
#包括
//链接以下功能C风格(插件需要)
外部“C”
{   
pcl::PointCloud::Ptr cloud(新的pcl::PointCloud);
///用两种不同的方式说同一件事
std::无序的_图八叉树图;
//std::无序的_图八叉树图;
//使用此选项对许多块没有影响;一个块可以使用和不使用
std::无序的云图;
导出API布尔createOcTree(字符*块名)
{
if(ocTreeMap.find(blockName)=ocTreeMap.end())
{
pcl::octree::OctreePointCloudSearch::Ptr八叉树(新pcl::octree::OctreePointCloudSearch(0.0025f));
八叉树->设置输入云(云);
八叉树->从InputCloud()添加点;
///使用此选项对许多块没有影响;一个块可以使用和不使用
if(cloudMap.find(blockName)!=cloudMap.end()
{
cloudMap.erase(blockName);
}
cloudMap[blockName]=云;
八叉树映射[块名]=八叉树;
返回true;
}
返回false;
}
导出API布尔发布八叉树(字符*块名)
{
if(ocTreeMap.erase(blockName)==0)
{
返回false;
}
其他的
{
///使用此选项对许多块没有影响;一个块可以使用和不使用
cloudMap.erase(blockName);
返回true;
}
}
导出API布尔findInOcTree(char*filePath、float originX、float originY、float originZ、float directionX、float directionY、float directionZ、float*hitX、float*hitY、float*hitZ)
{
本征::向量3f原点(originX,originY,originZ);
本征::矢量3f方向(方向X、方向Y、方向Z);
std::向量k_指数;
boost::shared_ptr octree=ocTreeMap[filePath];
///使用此选项对许多块没有影响;一个块可以使用和不使用
boost::shared_ptr pCloud=cloudMap[filePath];
八叉树->获取相交体素索引(原点、方向、k_索引,1);
如果(!k_index.empty())
{
*hitX=pCloud->points[k_index[0]].x;
*hitY=pCloud->points[k_index[0]].y;
*hitZ=pCloud->points[k_index[0]].z;
返回true;
}
返回false;
}
}

您似乎有多线程问题,但不清楚到底是什么问题。太多的元信息(虚拟现实、控制器…)会分散注意力,无助于理解实际问题。因此,如果您无法最小化您的示例,请更具体地说明您的多线程问题。无序的_映射在任何方面都不是线程安全的。到处都有数据竞赛。boost提供了支持并发的容器。使用它们将是第一步。再加上拉尔斯所写的:在阅读了你的第一段之后,我的最初反应是,这个问题不可能有什么成果。过多地关注高层上下文,而对实际问题关注不够(记住:这只是基于第一段)。不要试图将问题从上下文中抽象出来。上下文是好的,但作为结尾解释通常更好,而不是作为问题的引入。也许可以改变你解释的顺序?另见。