cnr-isti-vclab / vcglib

The VCGlib is a C++, templated, no dependency, library for manipulation, processing and cleaning of triangle meshes
http://vcg.isti.cnr.it/vcglib
GNU General Public License v3.0
1.15k stars 356 forks source link

PointCloud Normal Estimation #187

Open chenzongyi9708 opened 2 years ago

chenzongyi9708 commented 2 years ago

I am new with this lib, when using MeshLab,I find it can estimate the normal of pointcloud,and I want put it into my project,but it seems no examples show that how can i estimate pointcloud's normal.Only a example for estimation vertex's with face. How can I do that? Estimate a pointclou's normal like meshlab do?

gradywright commented 2 years ago

I'm not sure if this is the correct way to access the point cloud normal estimation routines, but here is some code I have used. Note inputs is an array of doubles (N-by-3) containing the point cloud data.

#include <iostream>
#include <vector>
#include <random>
#include <vcg/complex/complex.h>
#include <vcg/complex/algorithms/pointcloud_normal.h>

class MyVertex; class MyEdge; class MyFace;
struct MyUsedTypes : public vcg::UsedTypes<vcg::Use<MyVertex>   ::AsVertexType,
                                           vcg::Use<MyEdge>     ::AsEdgeType,
                                           vcg::Use<MyFace>     ::AsFaceType>{};
class MyVertex  : public vcg::Vertex< MyUsedTypes, vcg::vertex::Coord3d, vcg::vertex::Normal3d, vcg::vertex::BitFlags  >{};
class MyFace    : public vcg::Face<   MyUsedTypes, vcg::face::FFAdj,  vcg::face::VertexRef, vcg::face::BitFlags > {};
class MyEdge    : public vcg::Edge<   MyUsedTypes> {};
class MyMesh    : public vcg::tri::TriMesh< std::vector<MyVertex>, std::vector<MyFace> , std::vector<MyEdge>  > {};

.
.
.
.
.

MyMesh m;
uint neighborNum = 10;
uint smoothingIterNum = 1;

TypedArray<double> doubleArray = std::move(inputs[0]);
uint N = doubleArray.getNumberOfElements()/3;

Allocator<MyMesh>::AddVertices(m,N);
int idx = 0; 
for ( idx = 0; idx < N; idx++ ) {
    m.vert[idx].P() = MyMesh::CoordType(doubleArray[idx][0], doubleArray[idx][1], doubleArray[idx][2]);
}

vcg::tri::UpdateBounding<MyMesh>::Box(m); 

vcg::tri::PointCloudNormal<MyMesh>::Param p;
p.fittingAdjNum = fittingAdjNum;
p.smoothingIterNum = smoothingIterNum;
p.useViewPoint = 0;
vcg::tri::PointCloudNormal<MyMesh>::Compute(m, p, 0);

ArrayFactory f;
TypedArray<double> normal = f.createArray<double>({N, 3});
for ( idx = 0; idx < N; idx++ ) {
    normal[idx][0] = -m.vert[idx].N()[0];
    normal[idx][1] = -m.vert[idx].N()[1];
    normal[idx][2] = -m.vert[idx].N()[2];
}