[CC]手动点云分割

CloudCompare中手动点云分割功能ccGraphicalSegmentationTool,

点击应用按钮后将现有的点云分成segmented和remaining两个点云,

//停用点云分割功能
void MainWindow::deactivateSegmentationMode(bool state)

是通过ccPointCloud的可视选择集来实现的。其中用到了点云的swap需要参考!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
//创建新的点云,可视的选择集
ccGenericPointCloud* ccPointCloud::createNewCloudFromVisibilitySelection(bool removeSelectedPoints)
{
    if (!isVisibilityTableInstantiated())
    {
        ccLog::Error(QString("[Cloud %1] Visibility table not instantiated!").arg(getName()));
        return 0;
    }
 
    //we create a new cloud with the "visible" points
    ccPointCloud* result = 0;
    {
        //we create a temporary entity with the visible points only
        CCLib::ReferenceCloud* rc = getTheVisiblePoints();
        if (!rc)
        {
            //a warning message has already been issued by getTheVisiblePoints!
            //ccLog::Warning("[ccPointCloud::createNewCloudFromVisibilitySelection] An error occurred during points selection!");
            return 0;
        }
        assert(rc->size() != 0);
 
        //convert selection to cloud
        result = partialClone(rc);
 
        //don't need this one anymore
        delete rc;
        rc = 0;
    }
 
    if (!result)
    {
        ccLog::Warning("[ccPointCloud::createNewCloudFromVisibilitySelection] An error occurred during segmentation!");
        return 0;
    }
 
    result->setName(getName()+QString(".segmented"));//切割出来的点云
 
    //shall the visible points be erased from this cloud?
    if (removeSelectedPoints && !isLocked())
    {
        //we drop the octree before modifying this cloud's contents
        deleteOctree();
        clearLOD();
 
        unsigned count = size();
 
        //we have to take care of scan grids first
        {
            //we need a map between old and new indexes
            std::vector<int> newIndexMap(size(), -1);
            {
                unsigned newIndex = 0;
                for (unsigned i=0; i<count; ++i)
                {
                    if (m_pointsVisibility->getValue(i) != POINT_VISIBLE)
                        newIndexMap[i] = newIndex++;
                }
            }
 
            //then update the indexes
            UpdateGridIndexes(newIndexMap, m_grids);
 
            //and reset the invalid (empty) ones
            //(DGM: we don't erase them as they may still be useful?)
            for (size_t i=0; i<m_grids.size(); ++i)
            {
                Grid::Shared& scanGrid = m_grids[i];
                if (scanGrid->validCount == 0)
                {
                    scanGrid->indexes.clear();
                }
            }
        }
 
        //we remove all visible points
        unsigned lastPoint = 0;
        for (unsigned i=0; i<count; ++i)
        {
            //i持续增长,而lastPoint遇到==POINT_VISIBLE则跳过,起到迁移的效果
            if (m_pointsVisibility->getValue(i) != POINT_VISIBLE)
            {
                if (i != lastPoint)
                    swapPoints(lastPoint,i);
                ++lastPoint;
            }
        }
 
        //TODO: handle associated meshes
 
        resize(lastPoint);
         
        refreshBB(); //calls notifyGeometryUpdate + releaseVBOs
    }
 
    return result;
}

  调用的方法getTheVisiblePoints()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
CCLib::ReferenceCloud* ccGenericPointCloud::getTheVisiblePoints() const
{
    unsigned count = size();
    assert(count == m_pointsVisibility->currentSize());
 
    if (!m_pointsVisibility || m_pointsVisibility->currentSize() != count)
    {
        ccLog::Warning("[ccGenericPointCloud::getTheVisiblePoints] No visibility table instantiated!");
        return 0;
    }
 
    //count the number of points to copy
    unsigned pointCount = 0;
    {
        for (unsigned i=0; i<count; ++i)
            if (m_pointsVisibility->getValue(i) == POINT_VISIBLE)
                ++pointCount;
    }
 
    if (pointCount == 0)
    {
        ccLog::Warning("[ccGenericPointCloud::getTheVisiblePoints] No point in selection");
        return 0;
    }
 
    //we create an entity with the 'visible' vertices only
    CCLib::ReferenceCloud* rc = new CCLib::ReferenceCloud(const_cast<ccGenericPointCloud*>(this));
    if (rc->reserve(pointCount))
    {
        for (unsigned i=0; i<count; ++i)
            if (m_pointsVisibility->getValue(i) == POINT_VISIBLE)
                rc->addPointIndex(i); //can't fail (see above)
    }
    else
    {
        delete rc;
        rc = 0;
        ccLog::Error("[ccGenericPointCloud::getTheVisiblePoints] Not enough memory!");
    }
 
    return rc;
}

  

posted @   太一吾鱼水  阅读(2992)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示