Chi-Tech
chi_surfacemesh_splitbypatch.cc
Go to the documentation of this file.
1#include "chi_surfacemesh.h"
2
3/**Splits the surface by patch.*/
5 std::vector<chi_mesh::SurfaceMesh *> &patches)
6{
7 typedef std::vector<chi_mesh::Face> FaceList;
8 typedef std::vector<FaceList*> FaceListCollection;
9
10 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Copy all faces from surface
11 FaceList unsorted_faces;
12 FaceList::iterator cur_face;
13 for (cur_face = this->faces_.begin();
14 cur_face != this->faces_.end();
15 cur_face++)
16 {
17 unsorted_faces.push_back((*cur_face));
18 }
19
20 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Initialize co-planar collection
21 FaceListCollection co_planar_lists;
22
23 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Seed the first collection
24 FaceList* first_list = new FaceList;
25 co_planar_lists.push_back(first_list);
26 first_list->push_back(unsorted_faces.back());
27 unsorted_faces.pop_back();
28
29 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Reverse iterate over unsorted
30 FaceList::reverse_iterator us_face;
31 for (us_face = unsorted_faces.rbegin();
32 us_face != unsorted_faces.rend();
33 us_face++)
34 {
35 bool matchFound = false;
36
37 //====================================== Check if it can be matched
38 FaceListCollection::iterator existing_list;
39 for (existing_list = co_planar_lists.begin();
40 existing_list != co_planar_lists.end();
41 existing_list++)
42 {
43 for (cur_face = (*existing_list)->begin();
44 cur_face != (*existing_list)->end();
45 cur_face++)
46 {
47 chi_mesh::Normal n1 = cur_face->geometric_normal;
48 chi_mesh::Normal n2 = us_face->geometric_normal;
49
50 if (fabs(n1.Dot(n2))>(1.0-1.0e-4))
51 {
52 (*existing_list)->push_back(unsorted_faces.back());
53 unsorted_faces.pop_back();
54 matchFound = true;
55 break;
56 }
57 }
58 if (matchFound){break;}
59 }
60
61 //====================================== If no match found, create new list
62 if (!matchFound)
63 {
64 printf("New list created\n");
65 FaceList* new_list = new FaceList;
66 new_list->push_back(unsorted_faces.back());
67 unsorted_faces.pop_back();
68 co_planar_lists.push_back(new_list);
69 }
70 }
71
72 printf("Number of co-planar collections=%lu\n",co_planar_lists.size());
73
74 FaceListCollection patch_list_collection;
75
76 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Loop over co_planar lists
77 FaceListCollection::iterator existing_list;
78 for (existing_list = co_planar_lists.begin();
79 existing_list != co_planar_lists.end();
80 existing_list++)
81 {
82 //================================= Inner patch collection
83 FaceListCollection inner_patch_list_collection;
84
85 //================================= Add all the faces of this collection
86 // to an unused list
87 FaceList unused_faces;
88 for (cur_face = (*existing_list)->begin();
89 cur_face != (*existing_list)->end();
90 cur_face++)
91 {
92 unused_faces.push_back((*cur_face));
93 }
94
95 //================================= Seed the first patch list
96 FaceList* first_patch_list = new FaceList;
97 inner_patch_list_collection.push_back(first_patch_list);
98 first_patch_list->push_back(unused_faces.back());
99 unused_faces.pop_back();
100
101 //================================= Loop over unused faces
102 while (unused_faces.size()>0)
103 {
104 //printf("Unused faces=%d\n",unused_faces.size());
105 bool updateMade = false;
106 FaceList::iterator us_face_f; //Forward iterator
107 for (us_face_f = unused_faces.begin();
108 us_face_f != unused_faces.end();
109 us_face_f++)
110 {
111 //============================= Try to to find a home
112 FaceListCollection::iterator inner_list;
113 for (inner_list = inner_patch_list_collection.begin();
114 inner_list != inner_patch_list_collection.end();
115 inner_list++)
116 {
117 for (cur_face = (*inner_list)->begin();
118 cur_face != (*inner_list)->end();
119 cur_face++)
120 {
121 //==================== Check if any vertices match
122 for (int e=0; e<3; e++)
123 {
124 int vi = (*us_face_f).v_index[e];
125 for (int e2=0; e2<3; e2++)
126 {
127 int vf = (*cur_face).v_index[e2];
128
129 if (vf == vi)
130 {
131 (*inner_list)->push_back(*us_face_f);
132 unused_faces.erase(us_face_f);
133 updateMade = true;
134 break;
135 }
136 }
137 if (updateMade){break;}
138 }
139 if (updateMade){break;}
140 }
141 if (updateMade){break;}
142 }
143
144 if (updateMade){break;}
145 }
146
147 if (!updateMade)
148 {
149 FaceList* new_patch_list = new FaceList;
150 inner_patch_list_collection.push_back(new_patch_list);
151 new_patch_list->push_back(unused_faces.back());
152 unused_faces.pop_back();
153 }
154 }
155
156 //================================= Add inner patch lists to outer
157 FaceListCollection::iterator inner_list;
158 for (inner_list = inner_patch_list_collection.begin();
159 inner_list != inner_patch_list_collection.end();
160 inner_list++)
161 {
162 patch_list_collection.push_back(*inner_list);
163 }
164
165 }
166
167 printf("Number of patches = %lu\n", patch_list_collection.size());
168
169 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Create surfaces for each patch
170 FaceListCollection::iterator outer_patch;
171 for (outer_patch = patch_list_collection.begin();
172 outer_patch != patch_list_collection.end();
173 outer_patch++)
174 {
175
177
178 std::vector<int*> vertex_mapping;
179
180 for (cur_face = (*outer_patch)->begin();
181 cur_face != (*outer_patch)->end();
182 cur_face++)
183 {
184 //==================================== Copy the face
185 chi_mesh::Face newFace = (*cur_face);
186
187 //==================================== Copy and map vertices
188 for (int e=0;e<3;e++)
189 {
190 int vi = newFace.v_index[e];
191
192 //============================= Check if vertex already there
193 bool already_there = false;
194 int* already_there_mapping;
195 std::vector<int*>::iterator cur_map;
196 for (cur_map = vertex_mapping.begin();
197 cur_map != vertex_mapping.end();
198 cur_map++)
199 {
200 if ((*cur_map)[0] == vi)
201 {
202 already_there = true;
203 already_there_mapping = (*cur_map);
204 break;
205 }
206 }
207
208 if (already_there)
209 {
210 //=========================== Update vertex index
211 newFace.v_index[e] = already_there_mapping[1];
212 }
213 else
214 {
215 //=========================== Copy vertex
216 chi_mesh::Vertex v = this->vertices_.at(vi);
217 int* newMapping = new int[2];
218 newMapping[0] = vi;
219 newMapping[1] = new_surface->vertices_.size();
220
221 new_surface->vertices_.push_back(v);
222 vertex_mapping.push_back(newMapping);
223
224 newFace.v_index[e] = newMapping[1];
225 }
226
227
228 } //for e
229 newFace.e_index[0][0] = newFace.v_index[0];
230 newFace.e_index[0][1] = newFace.v_index[1];
231
232 newFace.e_index[1][0] = newFace.v_index[1];
233 newFace.e_index[1][1] = newFace.v_index[2];
234
235 newFace.e_index[2][0] = newFace.v_index[2];
236 newFace.e_index[2][1] = newFace.v_index[0];
237
238 for (int e=0;e<3;e++)
239 {
240 newFace.e_index[e][2] = -1;
241 newFace.e_index[e][3] = -1;
242 }
243
244 new_surface->faces_.push_back(newFace);
245 }
246 new_surface->UpdateInternalConnectivity();
247 //std::cout << (*new_surface);
248 patches.push_back(new_surface);
249
250
251
252// std::string fileName = "ZZMesh";
253// fileName = fileName + std::to_string((int)patches.size());
254// fileName = fileName + ".obj";
255//
256// std::cout <<fileName <<"\n";
257//
258// new_surface->ExportToOBJFile(fileName.c_str());
259 }
260}
void SplitByPatch(std::vector< chi_mesh::SurfaceMesh * > &patches)
std::vector< chi_mesh::Vertex > vertices_
std::vector< chi_mesh::Face > faces_
int v_index[3]
Definition: chi_meshface.h:8
int e_index[3][4]
Definition: chi_meshface.h:11
Vector3 Dot(const chi_mesh::TensorRank2Dim3 &that) const