mirror of
https://github.com/lucaspalomodevelop/meshlab.git
synced 2026-03-14 00:24:38 +00:00
filter mls uses a custom per vertex attribute for the radius
This commit is contained in:
parent
77a185f0d1
commit
c321c42e87
@ -316,9 +316,7 @@ std::map<std::string, QVariant> MlsPlugin::applyFilter(
|
||||
computeColorize(md, par, mls, pPoints, cb);
|
||||
break;
|
||||
case FP_RADIUS_FROM_DENSITY: {
|
||||
md.mm()->updateDataMask(MeshModel::MM_VERTRADIUS);
|
||||
APSS<CMeshO> mls(md.mm()->cm);
|
||||
mls.computeVertexRaddi(par.getInt("NbNeighbors"));
|
||||
GaelMls::computeVertexRadius(md.mm()->cm, par.getInt("NbNeighbors"));
|
||||
break;
|
||||
}
|
||||
case FP_SELECT_SMALL_COMPONENTS:
|
||||
@ -466,13 +464,7 @@ void MlsPlugin::initMLS(MeshDocument& md)
|
||||
}
|
||||
tri::Allocator<CMeshO>::CompactVertexVector(md.mm()->cm);
|
||||
|
||||
// We require a per vertex radius so as a first thing check it
|
||||
if (!md.mm()->hasDataMask(MeshModel::MM_VERTRADIUS)) {
|
||||
md.mm()->updateDataMask(MeshModel::MM_VERTRADIUS);
|
||||
APSS<CMeshO> mls(md.mm()->cm);
|
||||
mls.computeVertexRaddi();
|
||||
log("Mesh has no per vertex radius. Computed and added using default neighbourhood");
|
||||
}
|
||||
GaelMls::computeVertexRadius(md.mm()->cm);
|
||||
}
|
||||
|
||||
MeshModel* MlsPlugin::getProjectionPointsMesh(MeshDocument& md, const RichParameterList& params)
|
||||
|
||||
@ -71,8 +71,6 @@ private:
|
||||
void addColorizeParameters(RichParameterList& parlst, bool apss);
|
||||
void addMarchingCubesParameters(RichParameterList& parlst);
|
||||
|
||||
|
||||
|
||||
void initMLS(MeshDocument& md);
|
||||
MeshModel* getProjectionPointsMesh(MeshDocument& md, const RichParameterList& params);
|
||||
GaelMls::MlsSurface<CMeshO>* createMlsRimls(MeshModel* pPoints, const RichParameterList& par);
|
||||
|
||||
@ -29,9 +29,13 @@
|
||||
#include <iostream>
|
||||
#include <vcg/math/matrix33.h>
|
||||
#include <vcg/space/box3.h>
|
||||
#include <vcg/complex/allocate.h>
|
||||
|
||||
namespace GaelMls {
|
||||
|
||||
template<typename MeshType>
|
||||
void computeVertexRadius(MeshType& m, int nNeighbors = 16);
|
||||
|
||||
enum {
|
||||
MLS_OK,
|
||||
MLS_TOO_FAR,
|
||||
@ -58,11 +62,9 @@ public:
|
||||
|
||||
mAABB = mesh.bbox;
|
||||
|
||||
// compute radii using a basic meshless density estimator
|
||||
if (!mMesh.vert.RadiusEnabled) {
|
||||
const_cast<PointsType&>(mMesh.vert).EnableRadius();
|
||||
computeVertexRaddi();
|
||||
}
|
||||
typename MeshType::template ConstPerVertexAttributeHandle<Scalar> h;
|
||||
h = vcg::tri::Allocator<MeshType>::template FindPerVertexAttribute<Scalar>(mMesh, "radius");
|
||||
assert(vcg::tri::Allocator<MeshType>::IsValidHandle<Scalar>(mMesh, h));
|
||||
|
||||
mFilterScale = 4.0;
|
||||
mMaxNofProjectionIterations = 20;
|
||||
@ -149,16 +151,20 @@ public:
|
||||
}
|
||||
inline vcg::ConstDataWrapper<Scalar> radii() const
|
||||
{
|
||||
typename MeshType::template ConstPerVertexAttributeHandle<Scalar> h;
|
||||
h = vcg::tri::Allocator<MeshType>::template FindPerVertexAttribute<Scalar>(mMesh, "radius");
|
||||
assert(vcg::tri::Allocator<_MeshType>::template IsValidHandle<Scalar>(mMesh, h));
|
||||
|
||||
return vcg::ConstDataWrapper<Scalar>(
|
||||
&mMesh.vert[0].R(),
|
||||
&h[0],
|
||||
mMesh.vert.size(),
|
||||
size_t(&mMesh.vert[1].R()) - size_t(&mMesh.vert[0].R()));
|
||||
size_t(&h[1]) - size_t(&h[0]));
|
||||
}
|
||||
const vcg::Box3<Scalar>& boundingBox() const { return mAABB; }
|
||||
|
||||
static const Scalar InvalidValue() { return Scalar(12345679810.11121314151617); }
|
||||
|
||||
void computeVertexRaddi(const int nbNeighbors = 16);
|
||||
//void computeVertexRaddi(const int nbNeighbors = 16);
|
||||
|
||||
protected:
|
||||
void computeNeighborhood(const VectorType& x, bool computeDerivatives) const;
|
||||
|
||||
@ -26,9 +26,36 @@
|
||||
#include <limits>
|
||||
#include <vcg/space/index/kdtree/kdtree.h>
|
||||
#include <vcg/space/index/octree.h>
|
||||
#include <vcg/complex/base.h>
|
||||
#include <vcg/complex/allocate.h>
|
||||
|
||||
namespace GaelMls {
|
||||
|
||||
template<typename _MeshType>
|
||||
void computeVertexRadius(_MeshType& mesh, int nNeighbors)
|
||||
{
|
||||
typedef typename _MeshType::ScalarType Scalar;
|
||||
if (!vcg::tri::HasPerVertexAttribute(mesh, "radius")) {
|
||||
vcg::tri::Allocator<_MeshType>::template AddPerVertexAttribute<Scalar>(mesh, "radius");
|
||||
}
|
||||
|
||||
typename _MeshType::template PerVertexAttributeHandle<Scalar> h;
|
||||
h = vcg::tri::Allocator<_MeshType>::template FindPerVertexAttribute<Scalar>(mesh, "radius");
|
||||
assert(vcg::tri::Allocator<_MeshType>::template IsValidHandle<Scalar>(mesh, h));
|
||||
|
||||
auto positions = vcg::ConstDataWrapper<vcg::Point3<Scalar>>(
|
||||
&mesh.vert[0].P(),
|
||||
mesh.vert.size(),
|
||||
size_t(mesh.vert[1].P().V()) - size_t(mesh.vert[0].P().V()));
|
||||
|
||||
vcg::KdTree<Scalar> knn(positions);
|
||||
typename vcg::KdTree<Scalar>::PriorityQueue pq;
|
||||
for (size_t i = 0; i < mesh.vert.size(); i++) {
|
||||
knn.doQueryK(mesh.vert[i].cP(), nNeighbors, pq);
|
||||
h[i] = 2. * sqrt(pq.getTopWeight() / Scalarm(pq.getNofElements()));
|
||||
}
|
||||
}
|
||||
|
||||
template<typename _MeshType>
|
||||
void MlsSurface<_MeshType>::setFilterScale(Scalar v)
|
||||
{
|
||||
@ -66,23 +93,6 @@ void MlsSurface<_MeshType>::setHessianHint(int h)
|
||||
mCachedQueryPointIsOK = false;
|
||||
}
|
||||
|
||||
template<typename _MeshType>
|
||||
void MlsSurface<_MeshType>::computeVertexRaddi(const int nbNeighbors)
|
||||
{
|
||||
assert(mMesh.vert.size() >= 2);
|
||||
vcg::KdTree<Scalar> knn(positions());
|
||||
typename vcg::KdTree<Scalar>::PriorityQueue pq;
|
||||
// knn.setMaxNofNeighbors(nbNeighbors);
|
||||
mAveragePointSpacing = 0;
|
||||
for (size_t i = 0; i < mMesh.vert.size(); i++) {
|
||||
knn.doQueryK(mMesh.vert[i].cP(), nbNeighbors, pq);
|
||||
const_cast<PointsType&>(mMesh.vert)[i].R() =
|
||||
2. * sqrt(pq.getTopWeight() / Scalar(pq.getNofElements()));
|
||||
mAveragePointSpacing += mMesh.vert[i].cR();
|
||||
}
|
||||
mAveragePointSpacing /= Scalar(mMesh.vert.size());
|
||||
}
|
||||
|
||||
template<typename _MeshType>
|
||||
void MlsSurface<_MeshType>::computeNeighborhood(const VectorType& x, bool computeDerivatives) const
|
||||
{
|
||||
@ -102,9 +112,13 @@ void MlsSurface<_MeshType>::computeNeighborhood(const VectorType& x, bool comput
|
||||
else
|
||||
mCachedWeightGradients.clear();
|
||||
|
||||
typename _MeshType::template ConstPerVertexAttributeHandle<Scalar> h;
|
||||
h = vcg::tri::Allocator<_MeshType>::template FindPerVertexAttribute<Scalar>(mMesh, "radius");
|
||||
assert(vcg::tri::Allocator<_MeshType>::template IsValidHandle<Scalar>(mMesh, h));
|
||||
|
||||
for (size_t i = 0; i < nofSamples; i++) {
|
||||
int id = mNeighborhood.index(i);
|
||||
Scalar s = 1. / (mMesh.vert[id].cR() * mFilterScale);
|
||||
Scalar s = 1. / (h[id] * mFilterScale);
|
||||
s = s * s;
|
||||
Scalar w = Scalar(1) - mNeighborhood.squaredDistance(i) * s;
|
||||
if (w < 0)
|
||||
@ -124,6 +138,10 @@ void MlsSurface<_MeshType>::computeNeighborhood(const VectorType& x, bool comput
|
||||
template<typename _MeshType>
|
||||
void MlsSurface<_MeshType>::requestSecondDerivatives() const
|
||||
{
|
||||
typename _MeshType::template ConstPerVertexAttributeHandle<Scalar> h;
|
||||
h = vcg::tri::Allocator<_MeshType>::template FindPerVertexAttribute<Scalar>(mMesh, "radius");
|
||||
assert(vcg::tri::Allocator<_MeshType>::template IsValidHandle<Scalar>(mMesh, h));
|
||||
|
||||
// if (!mSecondDerivativeUptodate)
|
||||
{
|
||||
size_t nofSamples = mNeighborhood.size();
|
||||
@ -133,7 +151,7 @@ void MlsSurface<_MeshType>::requestSecondDerivatives() const
|
||||
{
|
||||
for (size_t i = 0; i < nofSamples; ++i) {
|
||||
int id = mNeighborhood.index(i);
|
||||
Scalar s = 1. / (mMesh.vert[id].cR() * mFilterScale);
|
||||
Scalar s = 1. / (h[id] * mFilterScale);
|
||||
s = s * s;
|
||||
Scalar x2 = s * mNeighborhood.squaredDistance(i);
|
||||
x2 = 1.0 - x2;
|
||||
@ -160,6 +178,11 @@ MlsSurface<_MeshType>::meanCurvature(const VectorType& gradient, const MatrixTyp
|
||||
template<typename _MeshType>
|
||||
bool MlsSurface<_MeshType>::isInDomain(const VectorType& x) const
|
||||
{
|
||||
typename _MeshType::template ConstPerVertexAttributeHandle<Scalar> h;
|
||||
h = vcg::tri::Allocator<_MeshType>::template FindPerVertexAttribute<Scalar>(mMesh, "radius");
|
||||
assert(vcg::tri::Allocator<_MeshType>::template IsValidHandle<Scalar>(mMesh, h));
|
||||
|
||||
|
||||
if ((!mCachedQueryPointIsOK) || mCachedQueryPoint != x) {
|
||||
computeNeighborhood(x, false);
|
||||
}
|
||||
@ -173,7 +196,7 @@ bool MlsSurface<_MeshType>::isInDomain(const VectorType& x) const
|
||||
if ((mDomainNormalScale == 1.f) || (!hasNormal)) {
|
||||
while (out && i < nb) {
|
||||
int id = mNeighborhood.index(i);
|
||||
Scalar rs2 = mMesh.vert[id].cR() * mDomainRadiusScale;
|
||||
Scalar rs2 = h[id] * mDomainRadiusScale;
|
||||
rs2 = rs2 * rs2;
|
||||
out = mNeighborhood.squaredDistance(i) > rs2;
|
||||
++i;
|
||||
@ -183,7 +206,7 @@ bool MlsSurface<_MeshType>::isInDomain(const VectorType& x) const
|
||||
Scalar s = 1. / (mDomainNormalScale * mDomainNormalScale) - 1.f;
|
||||
while (out && i < nb) {
|
||||
int id = mNeighborhood.index(i);
|
||||
Scalar rs2 = mMesh.vert[id].cR() * mDomainRadiusScale;
|
||||
Scalar rs2 = h[id] * mDomainRadiusScale;
|
||||
rs2 = rs2 * rs2;
|
||||
Scalar dn = mMesh.vert[id].cN().dot(x - mMesh.vert[id].cP());
|
||||
out = (mNeighborhood.squaredDistance(i) + s * dn * dn) > rs2;
|
||||
|
||||
@ -1 +1 @@
|
||||
Subproject commit fa6bab75912840168c7814d9157bf11bc5be4224
|
||||
Subproject commit 3bb6cfc71aa3081c4f8a30bce45df3bfcd0ce547
|
||||
Loading…
x
Reference in New Issue
Block a user