41 typedef typename TDomain::grid_type TGrid;
42 static const int dim = TDomain::dim;
44 auto river_posAcc = river_domain->position_accessor();
45 auto soil_posAcc = soil_domain->position_accessor();
46 auto soil_ssHandler = soil_domain->subset_handler();
47 auto river_grid = river_domain->grid();
48 auto soil_grid = soil_domain->grid();
50 const int top_subset_index = soil_ssHandler->get_subset_index(top_subset);
51 UG_ASSERT(top_subset_index > -1,
"project_rivers_on_terrain: Top subset '" << top_subset <<
"' not found.");
53 UG_LOG(
"Projecting river network onto terrain subset: " << top_subset <<
"\n");
56 auto tree = tree_type();
57 tree.create_from_grid(*soil_grid,
58 soil_ssHandler->template begin<Vertex>(top_subset_index, soil_grid->top_level()),
59 soil_ssHandler->template end<Vertex>(top_subset_index, soil_grid->top_level()),
66 std::set<Vertex*> skipped_vertices;
69 for (
size_t lvl = 0; lvl <= river_grid->top_level(); ++lvl) {
70 auto vIt = river_grid->template begin<Vertex>(lvl);
71 auto end = river_grid->template end<Vertex>(lvl);
73 for (; vIt != end; ++vIt) {
75 std::vector<Vertex*> neighborhood;
76 tree.get_neighbourhood(neighborhood, river_posAcc[vRiver], 1);
78 if (neighborhood.empty()) {
79 skipped_vertices.insert(vRiver);
83 Vertex* closest_soil_vertex = neighborhood[0];
84 typename TGrid::template traits<Face>::secure_container faces;
85 soil_grid->template associated_elements<Vertex>(faces, closest_soil_vertex);
88 for (
size_t i = 0; i < faces.size(); ++i) {
89 if (soil_ssHandler->get_subset_index(faces[i]) != top_subset_index)
continue;
93 *soil_grid, soil_posAcc,
SMALL)) {
95 river_posAcc[vRiver][dim - 1] =
PointOnRay(river_posAcc[vRiver], vDir, smin)[dim - 1];
101 skipped_vertices.insert(vRiver);
107 if (!skipped_vertices.empty()) {
108 UG_LOG(
"Handling " << skipped_vertices.size() <<
" vertices outside terrain extent...\n");
111 std::vector<Vertex*> to_process(skipped_vertices.begin(), skipped_vertices.end());
113 for (
Vertex* v : to_process) {
114 if (skipped_vertices.find(v) == skipped_vertices.end())
continue;
116 std::queue<Vertex*> q;
117 std::set<Vertex*> visited;
121 bool success =
false;
127 if (skipped_vertices.find(curr) == skipped_vertices.end()) {
128 river_posAcc[v][dim - 1] = river_posAcc[curr][dim - 1];
129 skipped_vertices.erase(v);
134 typename TGrid::template traits<Edge>::secure_container edges;
135 river_grid->template associated_elements<Vertex>(edges, curr);
136 for (
size_t i = 0; i < edges.size(); ++i) {
137 for (
int j = 0; j < 2; ++j) {
138 Vertex* nb = edges[i]->vertex(j);
139 if (visited.find(nb) == visited.end()) {
147 UG_THROW(
"Could not find a projected neighbor for vertex at " << river_posAcc[v]);
153 std::stringstream ss;
154 ss <<
"projected_river";
160 UG_LOG(
"Saving projected river grid to: " << ss.str() <<
"\n");
161 SaveGridToUGX(*river_grid, *(river_domain->subset_handler()), ss.str().c_str());
void project_rivers_on_terrain(SmartPtr< TDomain > river_domain, SmartPtr< TDomain > soil_domain, const char *top_subset)
Projects a 1D river network onto the surface of a 3D terrain.
Definition river_tools.h:39
bool RayElementIntersection(number &sminOut, number &smaxOut, const vector2 &from, const vector2 &dir, Edge *e, Grid &g, Grid::VertexAttachmentAccessor< AVector2 > aaPos, number sml=SMALL)