DgmOctree类的executeFunctionForAllCellsAtLevel和executeFunctionForAllCellsStartingAtLevel方法通过回调函数octreeCellFunc,执行八叉树中每个单元的相关计算。

unsigned DgmOctree::executeFunctionForAllCellsAtLevel(	unsigned char level,
octreeCellFunc func,
void** additionalParameters,
bool multiThread/*=false*/,
GenericProgressCallback* progressCb/*=0*/,
const char* functionTitle/*=0*/,
int maxThreadCount/*=0*/)

  

unsigned DgmOctree::executeFunctionForAllCellsStartingAtLevel(unsigned char startingLevel,
octreeCellFunc func,
void** additionalParameters,
unsigned minNumberOfPointsPerCell,
unsigned maxNumberOfPointsPerCell,
bool multiThread/* = true*/,
GenericProgressCallback* progressCb/*=0*/,
const char* functionTitle/*=0*/,
int maxThreadCount/*=0*/)

  通过DgmOctree遍历获取每一个Cell单元似乎还是一件很复杂的事情啊!

//! The coded octree structure
cellsContainer m_thePointsAndTheirCellCodes;

  通过编码集合实现?m_thePointsAndTheirCellCodes根据CellCodes对所有的点进行了排序。注意,所以知道每个Cell中的起始点的Index就可以确定Cell中的其他点。

	const cellsContainer& pointsAndTheirCellCodes() const
{
return m_thePointsAndTheirCellCodes;
}

  注意octreeCellFunc 回调函数的参数,第一个是const引用传递参数,值不可以修改。

typedef bool (*octreeCellFunc)(const octreeCell& cell, void**, NormalizedProgress*);

  因此尝试了使用下面的代码,应该是可行的:

if (!m_app)
return; const ccHObject::Container& selectedEntities = m_app->getSelectedEntities();
size_t selNum = selectedEntities.size();
if (selNum!=1)
{
m_app->dispToConsole("Select only one cloud!",ccMainAppInterface::ERR_CONSOLE_MESSAGE);
return;
} ccHObject* ent = selectedEntities[0];
assert(ent);
if (!ent || !ent->isA(CC_TYPES::POINT_CLOUD))
{
m_app->dispToConsole("Select a real point cloud!",ccMainAppInterface::ERR_CONSOLE_MESSAGE);
return;
} ccPointCloud* theCloud = static_cast<ccPointCloud*>(ent);
if (!theCloud)
return;
//输入参数,半径大小
float kernelRadius=1;
unsigned count = theCloud->size();
bool hasNorms = theCloud->hasNormals();
CCVector3 bbMin, bbMax;
theCloud->getBoundingBox(bbMin,bbMax);
const CCVector3d& globalShift = theCloud->getGlobalShift();
double globalScale = theCloud->getGlobalScale();
//进度条
ccProgressDialog pDlg(true,m_app->getMainWindow());
unsigned numberOfPoints = theCloud->size();
if (numberOfPoints < 5)
return ;
//构建八叉树
CCLib::DgmOctree* theOctree = NULL;
if (!theOctree)
{
theOctree = new CCLib::DgmOctree(theCloud);
if (theOctree->build(&pDlg) < 1)
{
delete theOctree;
return ;
}
}
int result = 0;
QString sfName="Eigen_Value";
int sfIdx = -1;
ccPointCloud* pc = 0;
//注意先添加ScalarField,并设置为当前的
if (theCloud->isA(CC_TYPES::POINT_CLOUD))
{
pc = static_cast<ccPointCloud*>(theCloud); sfIdx = pc->getScalarFieldIndexByName(qPrintable(sfName));
if (sfIdx < 0)
sfIdx = pc->addScalarField(qPrintable(sfName));
if (sfIdx >= 0)
pc->setCurrentInScalarField(sfIdx);
else
{
ccConsole::Error(QString("Failed to create scalar field on cloud '%1' (not enough memory?)").arg(pc->getName()));
}
}
//开启ScalarField模式
theCloud->enableScalarField();
//给定的半径,寻找最佳的Level
unsigned char level = theOctree->findBestLevelForAGivenNeighbourhoodSizeExtraction(kernelRadius); //parameters
void* additionalParameters[1] = {static_cast<void*>(&kernelRadius) }; if (theOctree->executeFunctionForAllCellsAtLevel(level,
&computeCellEigenValueAtLevel,
additionalParameters,
true,
&pDlg,
"Eigen value Computation") == 0)
{
//something went wrong
result = -4;
} //number of cells for this level
unsigned cellCount = theOctree->getCellNumber(level);
unsigned maxCellPopulation =theOctree->getmaxCellPopulation(level); //cell descriptor (initialize it with first cell/point)
CCLib::DgmOctree::octreeCell cell(theOctree);
if (!cell.points->reserve(maxCellPopulation)) //not enough memory
return;
cell.level = level;
cell.index = 0; CCLib::DgmOctree::cellIndexesContainer vec;
try
{
vec.resize(cellCount);
}
catch (const std::bad_alloc&)
{
//not enough memory
return;
} //binary shift for cell code truncation
unsigned char bitDec = GET_NDT_BIT_SHIFT(level); CCLib::DgmOctree::cellsContainer::const_iterator p =theOctree->pointsAndTheirCellCodes().begin(); CCLib::DgmOctree::OctreeCellCodeType predCode = (p->theCode >> bitDec)+1; //pred value must be different than the first element's for (unsigned i=0,j=0; i<theOctree->getNumberOfProjectedPoints(); ++i,++p)
{
CCLib::DgmOctree::OctreeCellCodeType currentCode = (p->theCode >> bitDec); if (predCode != currentCode)
{
vec[j++] = i;//存储索引 int n=cell.points->size();
if(n>=5)
{
CCVector3d Psum(0,0,0);
for (unsigned i=0; i<n; ++i)
{
CCVector3 P;
cell.points->getPoint(i,P);
Psum.x += P.x;
Psum.y += P.y;
Psum.z += P.z;
}
ScalarType curv = NAN_VALUE;
CCVector3 G(static_cast<PointCoordinateType>(Psum.x / n),
static_cast<PointCoordinateType>(Psum.y / n),
static_cast<PointCoordinateType>(Psum.z / n) ); double mXX = 0.0;
double mYY = 0.0;
double mZZ = 0.0;
double mXY = 0.0;
double mXZ = 0.0;
double mYZ = 0.0;
//for each point in the cell
for (unsigned i=0; i<n; ++i)
{
CCVector3 CellP;
cell.points->getPoint(i,CellP);
CCVector3 P = CellP - G; mXX += static_cast<double>(P.x)*P.x;
mYY += static_cast<double>(P.y)*P.y;
mZZ += static_cast<double>(P.z)*P.z;
mXY += static_cast<double>(P.x)*P.y;
mXZ += static_cast<double>(P.x)*P.z;
mYZ += static_cast<double>(P.y)*P.z;
}
//symmetry
CCLib::SquareMatrixd covMat(3);
covMat.m_values[0][0] = mXX/n;
covMat.m_values[1][1] = mYY/n;
covMat.m_values[2][2] = mZZ/n;
covMat.m_values[1][0] = covMat.m_values[0][1] = mXY/n;
covMat.m_values[2][0] = covMat.m_values[0][2] = mXZ/n;
covMat.m_values[2][1] = covMat.m_values[1][2] = mYZ/n; CCLib::SquareMatrixd eigVectors;
std::vector<double> eigValues; if (!Jacobi<double>::ComputeEigenValuesAndVectors(covMat, eigVectors, eigValues))
{
//failure
curv= NAN_VALUE;
}
//compute eigen value
double e0 = eigValues[0];
double e1 = eigValues[1];
double e2 = eigValues[2];
double sum = fabs(e0+e1+e2);
if (sum < ZERO_TOLERANCE)
{
curv= NAN_VALUE;
} double eMin = std::min(std::min(e0,e1),e2);
curv= static_cast<ScalarType>(fabs(eMin) / sum); for (unsigned i=0; i<n; ++i)
{
//current point index
unsigned index = cell.points->getPointGlobalIndex(i);
//current point index in neighbourhood (to compute curvature at the right position!)
unsigned indexInNeighbourhood = 0; cell.points->setPointScalarValue(i,curv);
}
} //and we start a new cell开始新的Cell
cell.index += cell.points->size();
cell.points->clear(false);
cell.truncatedCode = currentCode;
/*cell.mean_=G;
cell.cov_=covMat;
CCVector3 eigvalues1(e0,e1,e2);
cell.evals_=eigvalues1;*/
} cell.points->addPointIndex(p->theIndex); //can't fail (see above)
predCode = currentCode;
} if (result == 0)
{
if (pc && sfIdx >= 0)
{
//设置当前显示的ScalarField
pc->setCurrentDisplayedScalarField(sfIdx);
pc->showSF(sfIdx >= 0);
pc->getCurrentInScalarField()->computeMinAndMax();
}
theCloud->prepareDisplayForRefresh();
}
else
{
ccConsole::Warning(QString("Failed to apply processing to cloud '%1'").arg(theCloud->getName()));
if (pc && sfIdx >= 0)
{
pc->deleteScalarField(sfIdx);
sfIdx = -1;
}
}

  参考DgmOctree::getCellIndexes   DgmOctree::getPointsInCellByCellIndex

 //重要,获取每一八叉树层的Cell索引的集合
bool DgmOctreeNDT::getCellIndexes(unsigned char level, cellIndexesContainer& vec) const
{
try
{
vec.resize(m_cellCount[level]);
}
catch (const std::bad_alloc&)
{
//not enough memory
return false;
} //binary shift for cell code truncation
unsigned char bitDec = GET_NDT_BIT_SHIFT(level); cellsContainer::const_iterator p = m_thePointsAndTheirCellCodes.begin(); OctreeCellCodeType predCode = (p->theCode >> bitDec)+; //pred value must be different than the first element's for (unsigned i=,j=; i<m_numberOfProjectedPoints; ++i,++p)
{
OctreeCellCodeType currentCode = (p->theCode >> bitDec); if (predCode != currentCode)
vec[j++] = i; predCode = currentCode;
} return true;
}

DgmOctree::getCellIndexes

 bool DgmOctreeNDT::getPointsInCellByCellIndex(    ReferenceCloud* cloud,
unsigned cellIndex,
unsigned char level,
bool clearOutputCloud/* = true*/) const
{
assert(cloud && cloud->getAssociatedCloud() == m_theAssociatedCloud); //binary shift for cell code truncation
unsigned char bitDec = GET_NDT_BIT_SHIFT(level); //we look for the first index in 'm_thePointsAndTheirCellCodes' corresponding to this cell
cellsContainer::const_iterator p = m_thePointsAndTheirCellCodes.begin()+cellIndex;
OctreeCellCodeType searchCode = (p->theCode >> bitDec); if (clearOutputCloud)
cloud->clear(false); //while the (partial) cell code matches this cell
while ((p != m_thePointsAndTheirCellCodes.end()) && ((p->theCode >> bitDec) == searchCode))
{
if (!cloud->addPointIndex(p->theIndex))
return false;
++p;
} return true;
}

DgmOctree::getPointsInCellByCellIndex

  涉及的类包括:近邻点类、近邻点查询结构体

  另外:

 bool qNDTRansacSD::computeCellEigenValueAtLevel(const CCNDTLib::DgmOctreeNDT::octreeCellNDT& cell,
void** additionalParameters,NormalizedProgress* nProgress/*=0*/)
{
//parameters
PointCoordinateType radius = *static_cast<PointCoordinateType*>(additionalParameters[]); structure for nearest neighbors search
int n=cell.points->size();
CCVector3d Psum(,,);
for (unsigned i=; i<n; ++i)
{
CCVector3 P;
cell.points->getPoint(i,P);
Psum.x += P.x;
Psum.y += P.y;
Psum.z += P.z;
}
ScalarType curv = NAN_VALUE;
CCVector3 G(static_cast<PointCoordinateType>(Psum.x / n),
static_cast<PointCoordinateType>(Psum.y / n),
static_cast<PointCoordinateType>(Psum.z / n) ); double mXX = 0.0;
double mYY = 0.0;
double mZZ = 0.0;
double mXY = 0.0;
double mXZ = 0.0;
double mYZ = 0.0;
//for each point in the cell
for (unsigned i=; i<n; ++i)
{
CCVector3 CellP;
cell.points->getPoint(i,CellP);
CCVector3 P = CellP - G; mXX += static_cast<double>(P.x)*P.x;
mYY += static_cast<double>(P.y)*P.y;
mZZ += static_cast<double>(P.z)*P.z;
mXY += static_cast<double>(P.x)*P.y;
mXZ += static_cast<double>(P.x)*P.z;
mYZ += static_cast<double>(P.y)*P.z;
}
//symmetry
CCLib::SquareMatrixd covMat();
covMat.m_values[][] = mXX/n;
covMat.m_values[][] = mYY/n;
covMat.m_values[][] = mZZ/n;
covMat.m_values[][] = covMat.m_values[][] = mXY/n;
covMat.m_values[][] = covMat.m_values[][] = mXZ/n;
covMat.m_values[][] = covMat.m_values[][] = mYZ/n; CCLib::SquareMatrixd eigVectors;
std::vector<double> eigValues; if (!Jacobi<double>::ComputeEigenValuesAndVectors(covMat, eigVectors, eigValues))
{
//failure
curv= NAN_VALUE;
} //compute curvature as the rate of change of the surface
double e0 = eigValues[];
double e1 = eigValues[];
double e2 = eigValues[];
double sum = fabs(e0+e1+e2);
if (sum < ZERO_TOLERANCE)
{
curv= NAN_VALUE;
} double eMin = std::min(std::min(e0,e1),e2);
curv= static_cast<ScalarType>(fabs(eMin) / sum); for (unsigned i=; i<n; ++i)
{
//current point index
unsigned index = cell.points->getPointGlobalIndex(i);
//current point index in neighbourhood (to compute curvature at the right position!)
unsigned indexInNeighbourhood = ; cell.points->setPointScalarValue(i,curv);
if (nProgress && !nProgress->oneStep())
{
return false;
}
} return true;
}

qNDTRansacSD::computeCellEigenValueAtLevel

[CC]DgmOctree—执行Cell遍历和单元计算的更多相关文章

  1. DOM2级提供的对DOM结构执行深度优先遍历 笔记

    NodeIterator和TreeWalker这2个类型可以基于给定的起点对DOM结构执行深度优先遍历.(我测试用的浏览器是Chrome,介绍说IE不支持DOM遍历,但是不知道最新的IE支持不支持) ...

  2. MATLAB 的 cell 大法(单元格数组)

    MATLAB 的 cell,称单元格数组 or 元胞数组:使用频率特别高,甚至比 struct 结构体还高. MATLAB文档给出的 cell 官方定义: A cell array is a coll ...

  3. iOS不得姐项目--精华模块上拉下拉的注意事项,日期显示,重构子控制器,计算cell的高度(只计算一次),图片帖子的显示

    一.上拉下拉注意事项 使用MJRefresh中的上拉控件自动设置透明 当请求下页数据通过page的时候,注意的是上拉加载更多数据失败的问题,下拉加载数据失败了,页数应该还原.或者是请求成功的时候再将页 ...

  4. 在java代码中执行js脚本,实现计算出字符串“(1+2)*(1+3)”的结果

            今天在公司项目中,发现一个计算运费的妙招.由于运费规则各种各样,因此写一个公式存到数据库.下次需要计算运费时,直接取出这个公式,把公式的未知变量给替换掉,然后计算出结果就是ok了. 一 ...

  5. 自执行函数与setTimeout结合计算

    var v1=0,v2=0,v3=0;        for(var i=1;i<=3;i++){            var i2=i;            (function(){   ...

  6. 从锅炉工到AI专家(10)

    RNN循环神经网络(Recurrent Neural Network) 如同word2vec中提到的,很多数据的原型,前后之间是存在关联性的.关联性的打破必然造成关键指征的丢失,从而在后续的训练和预测 ...

  7. [CC]点云密度计算

    包括两种计算方法:精确计算和近似计算(思考:local density=单位面积的点数 vs  local density =1/单个点所占的面积) 每种方法可以实现三种模式的点云密度计算,CC里面的 ...

  8. Cell complex单元复合形

    概念 (1)Piecewise linear complex (PLC) 分段线性复合形 (2)Cell complex 单元复合形 [1] (元胞复合形) (3)Linear Cell Comple ...

  9. plv8 中使用 eval 函数执行表达式计算

    在js 开发中我们都说eval 函数是邪恶的,但是此函数也有好多妙用,以下是几个简单的案例 eval 执行基于js 的表达式计算 比如我们有以下表 CREATE TABLE rules (    id ...

随机推荐

  1. 分布式缓存技术redis学习系列(一)——redis简介以及linux上的安装

    redis简介 redis是NoSQL(No Only SQL,非关系型数据库)的一种,NoSQL是以Key-Value的形式存储数据.当前主流的分布式缓存技术有redis,memcached,ssd ...

  2. Pig语言基础-【持续更新中】

      ***本文参考了Pig官方文档以及已有的一些博客,并加上了自己的一些知识性的理解.目前正在持续更新中.***   Pig作为一种处理大规模数据的高级查询语言,底层是转换成MapReduce实现的, ...

  3. java-集合4

    浏览以下内容前,请点击并阅读 声明 对象排序 一个List对象中如果元素类型为String,则其按字母表顺序排序,而如果元素类型为Date,则按照年代排序,那如何判断元素的排序呢?String和Dat ...

  4. JS省市区三级联动

    不需要访问后台服务器端,不使用Ajax,无刷新,纯JS实现的省市区三级联动. 当省市区数据变动是只需调正js即可. 使用方法: <!DOCTYPE html><html>< ...

  5. 【原】iOS学习之应用程序的启动原理

    最近看视频了解了一下应用程序的启动原理,这里就做一个博客和大家分享一下,相互讨论,如果有什么补充或不同的意见可以提出来! 1.程序入口 众所周知,一个应用程序的入口一般是一个 main 函数,iOS也 ...

  6. ACM: FZU 2107 Hua Rong Dao - DFS - 暴力

    FZU 2107 Hua Rong Dao Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I6 ...

  7. SQLite部署-无法加载 DLL“SQLite.Interop.dll”: 找不到指定的模块

    近期刚使用SQLite,主要引用的是System.Data.SQLite.dll这个dll,在部署到测试环境时报无法加载 DLL“SQLite.Interop.dll”: 找不到指定的模块. (异常来 ...

  8. sqlserver2008 函数1

    SQL2008 表达式:是常量.变量.列或函数等与运算符的任意组合. 1. 字符串函数 函数 名称 参数 示例 说明 ascii(字符串表达式) select ascii('abc') 返回 97 返 ...

  9. Ajax校验

    一.Ajax简介 AJAX即(Asynchronous JavaScript and Xml)(异步JavaScript和XML),是指一种创建交互式网页应用的网页开发技术. Ajax的关键元素包括以 ...

  10. Deepin -Android Studio-Genymotion 之旅

    Deepin -Android Studio-Genymotion 之旅 暑假无聊中在deepin系统下配置好了android的开发环境,并使用了比较好的一款模拟器–Genymotion;下面是我配置 ...