MEPP2 Project
FaceIndicesUtilities.h
Go to the documentation of this file.
1 // Copyright (c) 2012-2019 University of Lyon and CNRS (France).
2 // All rights reserved.
3 //
4 // This file is part of MEPP2; you can redistribute it and/or modify
5 // it under the terms of the GNU Lesser General Public License as
6 // published by the Free Software Foundation; either version 3 of
7 // the License, or (at your option) any later version.
8 //
9 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
10 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
11 #pragma once
12 
13 #include <vector>
14 #include <set>
15 #include <stdexcept> // for std::invalid_argument
16 #include <algorithm> // for std::find
17 
18 namespace FEVV {
19 namespace FaceIndicesUtils {
20 template< typename IndexType >
21 bool
22 are_all_face_indices_unique(const std::vector< IndexType > &in_face_indices)
23 {
24  std::set< IndexType > s(in_face_indices.begin(), in_face_indices.end());
25  return (in_face_indices.size() == s.size());
26 }
27 
28 template< typename IndexType >
29 void
31  std::vector< std::vector< IndexType > > &in_out_lines_indices)
32 {
33  size_t nb_poly_lines = in_out_lines_indices.size();
34  for(size_t i = 0; i < nb_poly_lines; ++i)
35  {
36  size_t current_line_size = in_out_lines_indices[i].size();
37  if(current_line_size <= 2)
38  {
39  if(current_line_size <= 1)
40  throw std::invalid_argument(
41  "lines_indices_to_segments_indices -> input lines indices not "
42  "valid. Need at least 2 indices per line");
43 
44  continue;
45  }
46 
47  std::vector< IndexType > line_segment;
48  for(size_t j = 1; j < current_line_size;
49  ++j) // the first segment is kept at that level
50  {
51  switch(line_segment.size())
52  {
53  case 0:
54  line_segment.push_back(in_out_lines_indices[i][j]);
55  break;
56  case 2:
57  line_segment.erase(line_segment.begin());
58  // FALL THROUGH
59  case 1:
60  line_segment.push_back(in_out_lines_indices[i][j]);
61  in_out_lines_indices.push_back(line_segment);
62  }
63  }
64  while(in_out_lines_indices[i].size() > 2)
65  in_out_lines_indices[i].pop_back();
66  }
67 }
68 
69 template< typename IndexType >
70 void
72  const std::vector< IndexType >
73  &in_face_indices, // in order to work properly, each polyline length
74  // must be strictly less than the face degree minus 1
75  std::vector< IndexType >
76  &out_face_indices, // for the time being, we assume there is only one
77  // face described with the indices (only one loop)
78  std::vector< std::vector< IndexType > >
79  &out_lines_indices) // we can extract several dangling polylines
80 {
81  size_t nb_e = in_face_indices.size();
82  out_face_indices.clear();
83  out_lines_indices.clear();
84 
85  std::vector< IndexType > new_line;
86  bool found_elm_i = false, // true when an index is present 2 times and
87  // in-between these 2 occurences
88  preserve_next = true, // keep current face index
89  only_first_is_cleared = true;
90  IndexType where_found_i = -1;
91  for(IndexType i = 0; i < nb_e; ++i)
92  {
93  if(found_elm_i)
94  {
95  if(i == where_found_i)
96  {
97  found_elm_i = false;
98  preserve_next = !preserve_next;
99  where_found_i = -1;
100  if(new_line.size() > 1)
101  {
102  out_lines_indices.push_back(new_line);
103  new_line.clear();
104  }
105  continue; // to ensure that the same vertex is not added twice
106  }
107  }
108 
109  if(!preserve_next)
110  { // what is not preserved for face indices is used for polylines...
111  if(std::find(new_line.begin(), new_line.end(), in_face_indices[i]) ==
112  new_line.end())
113  new_line.push_back(in_face_indices[i]);
114  if(i == nb_e - 1)
115  out_lines_indices.push_back(new_line);
116  continue;
117  }
118 
119  for(IndexType j = i + 1; j < nb_e; ++j)
120  {
121  if(in_face_indices[i] == in_face_indices[j])
122  {
123  found_elm_i = true;
124  where_found_i = j;
125  if(j - i <= nb_e / 2)
126  {
127  preserve_next = false;
128  new_line.push_back(in_face_indices[i]);
129  }
130  else
131  {
132  if(only_first_is_cleared && (i > 0))
133  {
134  out_face_indices.clear();
135  only_first_is_cleared = false;
136  if(out_lines_indices.size() > 0)
137  out_lines_indices[out_lines_indices.size() - 1].insert(
138  out_lines_indices[out_lines_indices.size() - 1].begin(),
139  in_face_indices[i]);
140  }
141  else
142  new_line.push_back(in_face_indices[i]);
143  }
144  break;
145  }
146  }
147 
148  if(std::find(out_face_indices.begin(),
149  out_face_indices.end(),
150  in_face_indices[i]) == out_face_indices.end())
151  out_face_indices.push_back(in_face_indices[i]);
152  }
153 }
154 } // namespace FaceIndicesUtils
155 } // namespace FEVV
156 
FEVV::FaceIndicesUtils::lines_indices_to_segments_indices
void lines_indices_to_segments_indices(std::vector< std::vector< IndexType > > &in_out_lines_indices)
Definition: FaceIndicesUtilities.h:30
FEVV::FaceIndicesUtils::face_indices_to_face_and_lines_indices
void face_indices_to_face_and_lines_indices(const std::vector< IndexType > &in_face_indices, std::vector< IndexType > &out_face_indices, std::vector< std::vector< IndexType > > &out_lines_indices)
Definition: FaceIndicesUtilities.h:71
FEVV
Interfaces for plugins These interfaces will be used for different plugins.
Definition: Assert.h:16
FEVV::FaceIndicesUtils::are_all_face_indices_unique
bool are_all_face_indices_unique(const std::vector< IndexType > &in_face_indices)
Definition: FaceIndicesUtilities.h:22