filter mls uses a custom per vertex attribute for the radius

This commit is contained in:
alemuntoni 2021-10-14 17:09:37 +02:00
parent 77a185f0d1
commit c321c42e87
5 changed files with 61 additions and 42 deletions

View File

@ -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)

View File

@ -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);

View File

@ -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;

View File

@ -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