|
1 | 1 | /* |
2 | | - * Copyright 2017 Adobe. All rights reserved. |
| 2 | + * Copyright 2023 Adobe. All rights reserved. |
3 | 3 | * This file is licensed to you under the Apache License, Version 2.0 (the "License"); |
4 | 4 | * you may not use this file except in compliance with the License. You may obtain a copy |
5 | 5 | * of the License at http://www.apache.org/licenses/LICENSE-2.0 |
|
11 | 11 | */ |
12 | 12 | #pragma once |
13 | 13 |
|
14 | | -#include <cassert> |
15 | | -#include <limits> |
16 | | -#include <list> |
17 | | -#include <queue> |
18 | | -#include <vector> |
| 14 | +#ifdef LAGRANGE_ENABLE_LEGACY_FUNCTIONS |
| 15 | + #include <lagrange/legacy/compute_dijkstra_distance.h> |
| 16 | +#endif |
19 | 17 |
|
20 | | -#include <lagrange/Mesh.h> |
21 | | -#include <lagrange/common.h> |
22 | | -#include <lagrange/compute_triangle_normal.h> |
| 18 | +#include <lagrange/SurfaceMesh.h> |
| 19 | +#include <lagrange/utils/SmallVector.h> |
| 20 | +#include <optional> |
23 | 21 |
|
24 | 22 | namespace lagrange { |
25 | 23 |
|
26 | | -template <typename MeshType> |
27 | | -std::list<std::pair<typename MeshType::Index, typename MeshType::Scalar>> compute_dijkstra_distance( |
28 | | - MeshType& mesh, |
29 | | - typename MeshType::Index seed_facet_id, |
30 | | - const Eigen::Matrix<typename MeshType::Scalar, 3, 1>& bc, |
31 | | - typename MeshType::Scalar radius = 0.0) |
| 24 | +/// |
| 25 | +/// Option struct for compute_dijkstra_distance |
| 26 | +/// |
| 27 | +template <typename Scalar, typename Index> |
| 28 | +struct DijkstraDistanceOptions |
32 | 29 | { |
33 | | - using Scalar = typename MeshType::Scalar; |
34 | | - if (mesh.get_dim() != 3) { |
35 | | - throw std::runtime_error("Input mesh must be 3D mesh."); |
36 | | - } |
37 | | - if (mesh.get_vertex_per_facet() != 3) { |
38 | | - throw std::runtime_error("Input mesh is not triangle mesh"); |
39 | | - } |
40 | | - if (!mesh.has_facet_attribute("normal")) { |
41 | | - compute_triangle_normal(mesh); |
42 | | - } |
43 | | - if (!mesh.is_connectivity_initialized()) { |
44 | | - mesh.initialize_connectivity(); |
45 | | - } |
| 30 | + /// Seed facet index |
| 31 | + Index seed_facet = invalid<Index>(); |
46 | 32 |
|
47 | | - using Index = typename MeshType::Index; |
48 | | - using FacetType = Eigen::Matrix<Index, 3, 1>; |
49 | | - using VertexType = typename MeshType::VertexType; |
50 | | - using AttributeArray = typename MeshType::AttributeArray; |
| 33 | + /// Seed facet barycentric coordinate |
| 34 | + SmallVector<Scalar, 3> barycentric_coords; |
51 | 35 |
|
52 | | - if (radius <= 0.0) { |
53 | | - radius = std::numeric_limits<Scalar>::max(); |
54 | | - } |
55 | | - const Index num_facets = mesh.get_num_facets(); |
56 | | - const Index num_vertices = mesh.get_num_vertices(); |
57 | | - const auto& vertices = mesh.get_vertices(); |
58 | | - const auto& facets = mesh.get_facets(); |
59 | | - la_runtime_assert(seed_facet_id < num_facets); |
60 | | - const FacetType seed_facet = facets.row(seed_facet_id); |
61 | | - const VertexType seed_point = vertices.row(seed_facet[0]) * bc[0] + |
62 | | - vertices.row(seed_facet[1]) * bc[1] + |
63 | | - vertices.row(seed_facet[2]) * bc[2]; |
| 36 | + /// Maximum radius of the dijkstra distance |
| 37 | + Scalar radius = 0.0; |
64 | 38 |
|
65 | | - using Entry = std::pair<Index, Scalar>; |
66 | | - auto comp = [](const Entry& e1, const Entry& e2) { return e1.second > e2.second; }; |
67 | | - std::priority_queue<Entry, std::vector<Entry>, decltype(comp)> Q(comp); |
68 | | - AttributeArray dist(num_vertices, 1); |
69 | | - dist.setConstant(-1); |
70 | | - Q.push({seed_facet[0], (vertices.row(seed_facet[0]) - seed_point).norm()}); |
71 | | - Q.push({seed_facet[1], (vertices.row(seed_facet[1]) - seed_point).norm()}); |
72 | | - Q.push({seed_facet[2], (vertices.row(seed_facet[2]) - seed_point).norm()}); |
| 39 | + /// Output attribute name for dijkstra distance. |
| 40 | + std::string_view output_attribute_name = "@dijkstra_distance"; |
73 | 41 |
|
74 | | - std::list<Entry> involved_vts; |
75 | | - while (!Q.empty()) { |
76 | | - Entry entry = Q.top(); |
77 | | - involved_vts.push_back(entry); |
78 | | - Q.pop(); |
79 | | - Scalar curr_dist = dist(entry.first, 0); |
| 42 | + /// Output involved vertices |
| 43 | + bool output_involved_vertices = false; |
| 44 | +}; |
| 45 | + |
| 46 | + |
| 47 | +/// |
| 48 | +/// Computes dijkstra distance from a seed facet. |
| 49 | +/// |
| 50 | +/// @param mesh Input mesh. |
| 51 | +/// @param options Options for computing dijkstra distance. |
| 52 | +/// |
| 53 | +/// @tparam Scalar Mesh scalar type. |
| 54 | +/// @tparam Index Mesh index type. |
| 55 | +/// |
| 56 | +/// @return Optionally, a vector of indices of vertices involved |
| 57 | +/// |
| 58 | +template <typename Scalar, typename Index> |
| 59 | +std::optional<std::vector<Index>> compute_dijkstra_distance( |
| 60 | + SurfaceMesh<Scalar, Index>& mesh, |
| 61 | + const DijkstraDistanceOptions<Scalar, Index>& options = {}); |
80 | 62 |
|
81 | | - if (curr_dist < 0 || entry.second < curr_dist) { |
82 | | - dist(entry.first, 0) = entry.second; |
83 | | - const auto& adj_vertices = mesh.get_vertices_adjacent_to_vertex(entry.first); |
84 | | - for (const auto& vj : adj_vertices) { |
85 | | - Scalar d = entry.second + (vertices.row(vj) - vertices.row(entry.first)).norm(); |
86 | | - if (d < radius) { |
87 | | - Scalar next_dist = dist(vj, 0); |
88 | | - if (next_dist < 0 || d < next_dist) { |
89 | | - Q.push({vj, d}); |
90 | | - } |
91 | | - } |
92 | | - } |
93 | | - } |
94 | | - } |
95 | 63 |
|
96 | | - mesh.add_vertex_attribute("dijkstra_distance"); |
97 | | - mesh.import_vertex_attribute("dijkstra_distance", dist); |
98 | | - return involved_vts; |
99 | | -} |
100 | 64 | } // namespace lagrange |
0 commit comments