44 if(triangulation !=
nullptr) {
53 if(triangulation !=
nullptr) {
63 template <
typename triangulationType0,
typename triangulationType1>
64 int execute(
float *
const outputCoords,
65 const float *
const inputCoords,
66 const char *
const mask,
69 const triangulationType0 &triangulationToSmooth,
70 const triangulationType1 &triangulationSurface)
const;
72 struct Point :
public std::array<float, 3> {
75 res[0] = (*this)[0] + other[0];
76 res[1] = (*this)[1] + other[1];
77 res[2] = (*this)[2] + other[2];
82 res[0] = (*this)[0] * scalar;
83 res[1] = (*this)[1] * scalar;
84 res[2] = (*this)[2] * scalar;
88 return *
this + other * (-1);
91 return (*
this * (1.0F / scalar));
94 return os <<
'(' << pt[0] <<
" " << pt[1] <<
" " << pt[2] <<
')';
99 template <
typename triangulationType0,
typename triangulationType1>
101 std::vector<Point> &tmpStorage,
102 std::vector<SimplexId> &nearestVertexId,
103 std::vector<bool> &trianglesTested,
104 std::vector<SimplexId> &visitedTriangles,
105 std::vector<float> &dists,
106 const char *
const mask,
107 const triangulationType0 &triangulationToSmooth,
108 const triangulationType1 &triangulationSurface)
const;
118 template <
typename triangulationType>
121 std::vector<ttk::SurfaceGeometrySmoother::Point> &outputPoints,
122 const triangulationType &triangulationToSmooth)
const {
123 Point relaxed{outputPoints[a]};
124 const auto nneigh{triangulationToSmooth.getVertexNeighborNumber(a)};
127 triangulationToSmooth.getVertexNeighbor(a, i, neigh);
128 relaxed = relaxed + outputPoints[neigh];
130 return relaxed * (1.0F /
static_cast<float>(nneigh + 1));
136template <
typename triangulationType0,
typename triangulationType1>
138 std::vector<ttk::SurfaceGeometrySmoother::Point> &outputPoints,
139 std::vector<ttk::SurfaceGeometrySmoother::Point> &tmpStorage,
140 std::vector<SimplexId> &nearestVertexId,
141 std::vector<bool> &trianglesTested,
142 std::vector<SimplexId> &visitedTriangles,
143 std::vector<float> &dists,
144 const char *
const mask,
145 const triangulationType0 &triangulationToSmooth,
146 const triangulationType1 &triangulationSurface)
const {
149 std::stack<SimplexId> trianglesToTest{};
152#ifdef TTK_ENABLE_OPENMP4
153#pragma omp parallel for num_threads(threadNumber_) \
154 firstprivate(trianglesTested, visitedTriangles, dists, trianglesToTest)
156 for(
size_t i = 0; i < outputPoints.size(); i++) {
159 if(mask !=
nullptr && mask[i] == 0) {
160 tmpStorage[i] = outputPoints[i];
163 tmpStorage[i] = this->
relax(i, outputPoints, triangulationToSmooth);
170 dists, trianglesToTest,
false, triangulationToSmooth,
171 triangulationSurface);
173 tmpStorage[i] =
Point{res.pt};
174 nearestVertexId[i] = res.nearestVertex;
177 std::swap(outputPoints, tmpStorage);
179 this->
printMsg(
"Projected " + std::to_string(outputPoints.size()) +
" points",
186template <
typename triangulationType0,
typename triangulationType1>
188 float *
const outputCoords,
189 const float *
const inputCoords,
190 const char *
const mask,
193 const triangulationType0 &triangulationToSmooth,
194 const triangulationType1 &triangulationSurface)
const {
196 const auto nPoints{triangulationToSmooth.getNumberOfVertices()};
197 if(triangulationSurface.getDimensionality() != 2) {
198 this->
printErr(
"Can only project onto a surface");
202 if(triangulationToSmooth.getDimensionality() < 1
203 || triangulationToSmooth.getDimensionality() > 2) {
204 this->
printErr(
"Can only project a 1D or a 2D triangulated object");
209 this->
printMsg(
"Smoothing " + std::to_string(nPoints) +
" points in "
210 + std::to_string(nIter) +
" iterations...");
214 std::vector<bool> trianglesTested(
215 triangulationSurface.getNumberOfTriangles(),
false);
216 std::vector<SimplexId> visitedTriangles{};
218 std::vector<float> dists(triangulationSurface.getNumberOfVertices());
221 std::vector<ttk::SurfaceGeometrySmoother::Point> outputPoints(nPoints),
223 std::vector<SimplexId> nearestVertexId(nPoints);
226#ifdef TTK_ENABLE_OPENMP
227#pragma omp parallel for num_threads(threadNumber_)
230 outputPoints[i][0] = inputCoords[3 * i + 0];
231 outputPoints[i][1] = inputCoords[3 * i + 1];
232 outputPoints[i][2] = inputCoords[3 * i + 2];
237 if(vertsId !=
nullptr) {
238#ifdef TTK_ENABLE_OPENMP
239#pragma omp parallel for num_threads(threadNumber_)
242 nearestVertexId[i] = vertsId[i];
251#ifdef TTK_ENABLE_OPENMP
252#pragma omp parallel for num_threads(threadNumber_) firstprivate(dists)
256 outputPoints[i].data(), dists, triangulationSurface);
258 this->
printMsg(
"Computed nearest vertices", 1.0, tm_nv.getElapsedTime(),
259 this->threadNumber_);
262 for(
int i = 0; i < nIter; ++i) {
263 this->
relaxProject(outputPoints, tmpStorage, nearestVertexId,
264 trianglesTested, visitedTriangles, dists, mask,
265 triangulationToSmooth, triangulationSurface);
269#ifdef TTK_ENABLE_OPENMP
270#pragma omp parallel for num_threads(threadNumber_)
273 outputCoords[3 * i + 0] = outputPoints[i][0];
274 outputCoords[3 * i + 1] = outputPoints[i][1];
275 outputCoords[3 * i + 2] = outputPoints[i][2];
278 this->
printMsg(
"Smoothed " + std::to_string(nPoints) +
" points", 1.0,
279 tm.getElapsedTime(), this->threadNumber_);
boost::tuple< double, double > Point
AbstractTriangulation is an interface class that defines an interface for efficient traversal methods...
virtual int preconditionVertexStars()
virtual int preconditionVertexEdges()
virtual int preconditionVertexNeighbors()
virtual int preconditionEdgeTriangles()
virtual int preconditionEdges()
virtual int getDimensionality() const
virtual int preconditionVertexTriangles()
virtual int preconditionTriangles()
int printErr(const std::string &msg, const debug::LineMode &lineMode=debug::LineMode::NEW, std::ostream &stream=std::cerr) const
~SurfaceGeometrySmoother() override=default
int relaxProject(std::vector< Point > &outputPoints, std::vector< Point > &tmpStorage, std::vector< SimplexId > &nearestVertexId, std::vector< bool > &trianglesTested, std::vector< SimplexId > &visitedTriangles, std::vector< float > &dists, const char *const mask, const triangulationType0 &triangulationToSmooth, const triangulationType1 &triangulationSurface) const
SurfaceGeometrySmoother()
int execute(float *const outputCoords, const float *const inputCoords, const char *const mask, const SimplexId *const vertsId, const int nIter, const triangulationType0 &triangulationToSmooth, const triangulationType1 &triangulationSurface) const
void preconditionTriangulationSurface(AbstractTriangulation *const triangulation)
void preconditionTriangulationToSmooth(AbstractTriangulation *const triangulation)
Point relax(const SimplexId a, std::vector< ttk::SurfaceGeometrySmoother::Point > &outputPoints, const triangulationType &triangulationToSmooth) const
Computes the barycenter of a given point's neighbors.
SimplexId getNearestSurfaceVertex(const T *pa, std::vector< T > &dists, const triangulationType &triangulation)
Find nearest vertex on the surface.
ProjectionResult findProjection(const ProjectionInput &pi, VisitedMask &trianglesTested, std::vector< float > &dists, std::stack< SimplexId > &trianglesToTest, const bool reverseProjection, const triangulationType0 &triangulationToSmooth, const triangulationType1 &triangulation)
TTK base package defining the standard types.
int SimplexId
Identifier type for simplices of any dimension.
friend std::ostream & operator<<(std::ostream &os, const Point &pt)
Point operator-(Point other) const
Point operator/(const float scalar) const
Point operator*(const float scalar) const
Point operator+(const Point other) const
Auto-cleaning re-usable graph propagations data structure.
printMsg(debug::output::BOLD+" | | | | | . \\ | | (__| | / __/| |_| / __/| (_) |"+debug::output::ENDCOLOR, debug::Priority::PERFORMANCE, debug::LineMode::NEW, stream)