40 if(triangulation ==
nullptr) {
55 return nVertices_ + nEdges_ + nTriangles_;
61 return nTriangles_ * 6;
64 template <
typename triangulationType>
65 int execute(
const triangulationType &inputTriangl,
79 template <
typename T,
typename triangulationType>
81 const T *data, T *output,
const triangulationType &inputTriangl)
const {
83 std::is_floating_point<T>::value,
"Floating point type required.");
85 if(nOutVerts < 0 || nOutVerts != nVertices_ + nEdges_ + nTriangles_) {
90 std::copy(data, data + nVertices_, output);
95 inputTriangl.getEdgeVertex(i, 0, a);
96 inputTriangl.getEdgeVertex(i, 0, b);
97 output[nVertices_ + i] = (data[a] + data[b]) / T{2.0};
101 for(
SimplexId i = 0; i < nTriangles_; ++i) {
103 inputTriangl.getTriangleVertex(i, 0, a);
104 inputTriangl.getTriangleVertex(i, 1, b);
105 inputTriangl.getTriangleVertex(i, 2, c);
106 output[nVertices_ + nEdges_ + i]
107 = (data[a] + data[b] + data[c]) / T{3.0};
122 template <
typename T>
125 static_assert(std::is_integral<T>::value,
"Integral type required.");
127 if(nOutVerts < 0 || nOutVerts < nVertices_) {
130 std::fill(output, output + nOutVerts, T{0});
131 std::copy(data, data + nVertices_, output);
145 template <
typename T>
148 const size_t newTrianglesPerParent{6};
150 if(nOutTriangles != newTrianglesPerParent * nTriangles_) {
153 for(
SimplexId i = 0; i < nTriangles_; ++i) {
154 output[i * newTrianglesPerParent + 0] = data[i];
155 output[i * newTrianglesPerParent + 1] = data[i];
156 output[i * newTrianglesPerParent + 2] = data[i];
157 output[i * newTrianglesPerParent + 3] = data[i];
158 output[i * newTrianglesPerParent + 4] = data[i];
159 output[i * newTrianglesPerParent + 5] = data[i];
165 template <
typename triangulationType>
166 int subdiviseTriangulation(
const triangulationType &inputTriangl);
190template <
typename triangulationType>
191int ttk::BarycentricSubdivision::subdiviseTriangulation(
192 const triangulationType &inputTriangl) {
194 const SimplexId newPoints{nVertices_ + nEdges_ + nTriangles_};
195 const size_t dataPerPoint{3};
197 points_.resize(newPoints * dataPerPoint);
199 const size_t dataPerCell{3};
200 const size_t newTrianglesPerParent{6};
213 for(
SimplexId i = 0; i < nVertices_; ++i) {
214 inputTriangl.getVertexPoint(
220 points_.reserve(newPoints * dataPerPoint);
226 inputTriangl.getEdgeVertex(i, 0, a);
227 inputTriangl.getEdgeVertex(i, 1, b);
229 std::array<float, 3> pa{}, pb{}, mid{};
230 inputTriangl.getVertexPoint(a, pa[0], pa[1], pa[2]);
231 inputTriangl.getVertexPoint(b, pb[0], pb[1], pb[2]);
233 mid[0] = (pa[0] + pb[0]) / 2.0F;
234 mid[1] = (pa[1] + pb[1]) / 2.0F;
235 mid[2] = (pa[2] + pb[2]) / 2.0F;
237 const size_t offset = dataPerPoint * (nVertices_ + i);
246 for(
SimplexId i = 0; i < nTriangles_; ++i) {
249 inputTriangl.getTriangleVertex(i, 0, a);
250 inputTriangl.getTriangleVertex(i, 1, b);
251 inputTriangl.getTriangleVertex(i, 2, c);
253 std::array<float, 3> pa{}, pb{}, pc{}, bary{};
254 inputTriangl.getVertexPoint(a, pa[0], pa[1], pa[2]);
255 inputTriangl.getVertexPoint(b, pb[0], pb[1], pb[2]);
256 inputTriangl.getVertexPoint(c, pc[0], pc[1], pc[2]);
258 bary[0] = (pa[0] + pb[0] + pc[0]) / 3.0F;
259 bary[1] = (pa[1] + pb[1] + pc[1]) / 3.0F;
260 bary[2] = (pa[2] + pb[2] + pc[2]) / 3.0F;
262 const size_t offset = dataPerPoint * (nVertices_ + nEdges_ + i);
266 pointId_[nVertices_ + nEdges_ + i] = i;
272 for(
SimplexId i = 0; i < nTriangles_; ++i) {
274 const SimplexId bary = nVertices_ + nEdges_ + i;
276 for(
SimplexId j = 0; j < inputTriangl.getTriangleEdgeNumber(i); ++j) {
279 inputTriangl.getTriangleEdge(i, j, e);
286 inputTriangl.getEdgeVertex(e, 0, a);
287 inputTriangl.getEdgeVertex(e, 1, b);
312template <
typename triangulationType>
314 const triangulationType &inputTriangl,
318 if(inputTriangl.getDimensionality() >= 3) {
319 this->printErr(
"Not yet implemented for dimension 3 and above");
325 const SimplexId vertexNumber = inputTriangl.getNumberOfVertices();
326 subdiviseTriangulation(inputTriangl);
327 buildOutputTriangulation(outputTriangl);
330 "Data-set (" + std::to_string(vertexNumber) +
" points) processed", 1.0,
AbstractTriangulation is an interface class that defines an interface for efficient traversal methods...
virtual int preconditionVertexNeighbors()
virtual int preconditionTriangleEdges()
virtual int preconditionEdges()
virtual SimplexId getNumberOfVertices() const
virtual SimplexId getNumberOfTriangles() const
virtual int preconditionTriangles()
virtual SimplexId getNumberOfEdges() const
Subdivise a triangulation according to triangle barycenter.
int interpolateContinuousScalarField(const T *data, T *output, const triangulationType &inputTriangl) const
Interpolate floating-point point data on subdivised triangulation.
SimplexId getNumberOfVertices() const
Return the number of vertices in the output triangulation.
std::vector< float > points_
std::vector< LongSimplexId > cells_connectivity_
void preconditionTriangulation(AbstractTriangulation *const triangulation)
int execute(const triangulationType &inputTriangl, ExplicitTriangulation &outputTriangl)
int interpolateCellDataField(const T *data, T *output) const
Interpolate cell data on subdivised triangulation.
std::vector< SimplexId > pointId_
SimplexId getNumberOfTriangles() const
Return the number of triangles in the output triangulation.
std::vector< LongSimplexId > cells_offsets_
int interpolateDiscreteScalarField(const T *data, T *output) const
Interpolate integer point data on subdivised triangulation.
std::vector< SimplexId > pointDim_
Minimalist debugging class.
void setDebugMsgPrefix(const std::string &prefix)
ExplicitTriangulation is a class that provides time efficient traversal methods on triangulations of ...
long long int LongSimplexId
Identifier type for simplices of any dimension.
int SimplexId
Identifier type for simplices of any dimension.
printMsg(debug::output::BOLD+" | | | | | . \\ | | (__| | / __/| |_| / __/|__ _|"+debug::output::ENDCOLOR, debug::Priority::PERFORMANCE, debug::LineMode::NEW, stream)