PeriDyno 1.0.0
Loading...
Searching...
No Matches
TetraMeshWriterFracture.cpp
Go to the documentation of this file.
3
4#include <sstream>
5#include <iostream>
6#include <fstream>
7#include <cstdio>
8#include <cstring>
9#include <stdlib.h>
10#include <algorithm>
11
12namespace dyno
13{
15
16 template<typename TDataType>
21
22 template<typename TDataType>
26
27
28
30 {
31 return a.maxVertexID() < b.maxVertexID();
32 }
33
34 template<typename TDataType>
36 {
37 if (filename.size() < 5 || filename.substr(filename.size() - 4) != std::string(".obj")) {
38 std::cerr << "Error: Expected OBJ file with filename of the form <name>.obj.\n";
39 exit(-1);
40 }
41
42 std::ifstream infile(filename);
43 if (!infile) {
44 std::cerr << "Failed to open. Terminating.\n";
45 exit(-1);
46 }
47
48 int ignored_lines = 0;
49 std::string line;
50 std::vector<Coord> vertList;
51 std::vector<Triangle> faceList;
52 std::vector<Triangle> faceVnList;
53 while (!infile.eof()) {
54 std::getline(infile, line);
55 //std::cout << line << std::endl;
56 //.obj files sometimes contain vertex normals indicated by "vn"
57 if (line.substr(0, 1) == std::string("v") && line.substr(0, 2) != std::string("vn") && line.substr(0, 2) != std::string("vt")) {
58 std::stringstream data(line);
59 char c;
60 Coord point;
61 data >> c >> point[0] >> point[1] >> point[2];
62 vertList.push_back(point);
63 }
64 else if (line.substr(0, 2) == std::string("vt"))
65 {
66 std::stringstream data(line);
67 char c[20];
68 Coord point;
69 data >> c >> point[0] >> point[1];
70 point[2] = 0.0f;
71 vnList.push_back(point);
72 }
73 else if (line.substr(0, 1) == std::string("f")) {
74 std::stringstream data(line);
75 char c;
76 char ss1[30];
77 char ss2[30];
78 char ss3[30];
79 int v0, v1, v2;
80 v0 = v1 = v2 = 0;
81 int vt0, vt1, vt2;
82 vt0 = vt1 = vt2 = 0;
83
84 data >> c >> ss1 >> ss2 >> ss3;
85
86 bool cnt = false;
87 for (int i = 0; i < strlen(ss1); i++)
88 {
89 if (!cnt)
90 {
91 if (ss1[i] == '/') cnt = true;
92 else
93 {
94 v0 *= 10;
95 v0 += ss1[i] - '0';
96 }
97 }
98 else
99 {
100 if (ss1[i] == '/') break;
101 else
102 {
103 vt0 *= 10;
104 vt0 += ss1[i] - '0';
105 }
106 }
107 }
108
109 cnt = false;
110 for (int i = 0; i < strlen(ss2); i++)
111 {
112 if (!cnt)
113 {
114 if (ss2[i] == '/') cnt = true;
115 else
116 {
117 v1 *= 10;
118 v1 += ss2[i] - '0';
119 }
120 }
121 else
122 {
123 if (ss2[i] == '/') break;
124 else
125 {
126 vt1 *= 10;
127 vt1 += ss2[i] - '0';
128 }
129 }
130 }
131
132 cnt = false;
133 for (int i = 0; i < strlen(ss3); i++)
134 {
135 if (!cnt)
136 {
137 if (ss3[i] == '/') cnt = true;
138 else
139 {
140 v2 *= 10;
141 v2 += ss3[i] - '0';
142 }
143 }
144 else
145 {
146 if (ss3[i] == '/') break;
147 else
148 {
149 vt2 *= 10;
150 vt2 += ss3[i] - '0';
151 }
152 }
153 }
154 /*std::cout << v0 << ' ' << v1 << ' ' << v2 << std::endl;
155 std::cout << vt0 << ' ' << vt1 << ' ' << vt2 << std::endl;*/
156 faceList.push_back(Triangle(v0 - 1, v1 - 1, v2 - 1));
157 faceVnList.push_back(Triangle(vt0, vt1, vt2));
158 }
159 else {
160 ++ignored_lines;
161 }
162 }
163
164 printf("end\n");
165
166 infile.close();
167 std::cout << faceList.size() << std::endl;
168 FaceId.resize(faceList.size());
169 for (int i = 0; i < faceList.size(); i++)
170 {
171 FaceId[i].vertexId1 = faceList[i][0];
172 FaceId[i].vertexId2 = faceList[i][1];
173 FaceId[i].vertexId3 = faceList[i][2];
174 FaceId[i].uvId1 = faceVnList[i][0];
175 FaceId[i].uvId2 = faceVnList[i][1];
176 FaceId[i].uvId3 = faceVnList[i][2];
177 }
178 std::sort(FaceId.begin(), FaceId.begin() + faceList.size(), cmp);
179
180 FaceStart.resize(vertList.size());
181
182 //std::cout << vertList.size() << std::endl;
183 for (int i = 0; i < FaceStart.size(); i++)
184 FaceStart[i] = -1;
185 for (int i = 0; i < FaceId.size(); i++)
186 {
187 if (i == 0 || FaceId[i].maxVertexID() != FaceId[i - 1].maxVertexID())
188 {
189 FaceStart[FaceId[i].maxVertexID()] = i;
190 }
191 }
192 printf("outside\n");
193
194 }
195
196 template<typename TDataType>
198 {
199 if (this->ptr_TetrahedronSet == nullptr) {
200 return false;
201 }
202 this->ptr_triangles = &( this->ptr_TetrahedronSet->getTriangles() );
203 this->ptr_tri2tet = &( this->ptr_TetrahedronSet->getTri2Tet() );
204 this->ptr_vertices = &( this->ptr_TetrahedronSet->getPoints() );
205 this->ptr_tets = &( this->ptr_TetrahedronSet->getTetrahedrons() );
206 }
207
208 template<typename TDataType>
210 {
211 int maximum_index = glm::max(glm::max(Tri[0], Tri[1]), Tri[2]);
212 int minimum_index = glm::min(glm::min(Tri[0], Tri[1]), Tri[2]);
213 int sum_index = Tri[0] + Tri[1] + Tri[2];
214
215 /*if(maximum_index > FaceStart.size())
216 std::cout << "!!!!!" << maximum_index << ' ' << FaceStart.size() << std::endl;*/
217 if (maximum_index < 0) return -1;
218
219 if(FaceStart[maximum_index] == -1)
220 return -1;
221 //std::cout<< FaceStart[maximum_index] <<' '<< FaceId.size() << std::endl;
222 for (int i = FaceStart[maximum_index]; i < FaceId.size() && FaceId[i].maxVertexID() == maximum_index; i++)
223 {
224 if(FaceId[i].minVertexID() == minimum_index && FaceId[i].sumVertexID() == sum_index)
225 return i;
226 }
227 return -1;
228 }
229
230
231 template<typename TDataType>
233 {
234
235 if (this->ptr_tri2tet == nullptr || this->ptr_triangles == nullptr || this->ptr_vertices == nullptr) {
236 printf("------Tetra Mesh Writer: array nullptr \n");
237 return false;
238 }
239
240 std::string filename = this->constructFileName() + this->file_postfix;
241 std::string filenameF = this->constructFileName() + this->file_postfix;
242 std::ofstream output(filename.c_str(), std::ios::out);
243 std::ofstream outputF(filenameF.c_str(), std::ios::out);
244
245 if (!output.is_open()) {
246 printf("------Tetra Mesh Writer: open file failed \n");
247 return false;
248 }
249
250 this->updatePtr();
251
252 CArray<Coord> host_vertices;
253 CArray<Triangle> host_triangles;
254 CArray<Tri2Tet> host_tri2tet;
255 CArray<Tetrahedron> host_tets;
256 CArray<int> host_VerId;
257
258 host_vertices.resize( (*(this->ptr_vertices)).size() );
259 host_triangles.resize( (*(this->ptr_triangles)).size() );
260 host_tri2tet.resize( (*(this->ptr_tri2tet)).size() );
261 host_tets.resize((*(this->ptr_tets)).size());
262
263 host_VerId.resize((*(this->ptr_vertices)).size());
264 host_VerId.assign((*OringalID));
265
266 std::cout << host_VerId.size() << std::endl;
267
268 host_vertices.assign(*(this->ptr_vertices));
269 host_triangles.assign(*(this->ptr_triangles));
270 host_tri2tet.assign(*(this->ptr_tri2tet));
271 host_tets.assign(*(this->ptr_tets));
272
273
274 if (first)
275 {
276 first = false;
277 onFace.resize(host_VerId.size());
278 FaceMapping.resize(host_VerId.size());
279 for (int i = 0; i < onFace.size(); i++)
280 onFace[i] = 1;
281
282 for (int i = 0; i < host_tri2tet.size(); ++i) {
283 Tri2Tet tmp = host_tri2tet[i];
284 bool isOnSurface = false;
285 if (tmp[0] < 0 || tmp[1] < 0) { isOnSurface = true; }
286 if (isOnSurface)
287 {
288 onFace[host_triangles[i][0]] = true;
289 onFace[host_triangles[i][1]] = true;
290 onFace[host_triangles[i][2]] = true;
291 }
292 }
293 int mapping_last = 0;
294 for (int i = 0; i < onFace.size(); i++)
295 {
296 if (onFace[i])
297 {
298 FaceMapping[i] = mapping_last;
299 mapping_last++;
300 }
301 else
302 FaceMapping[i] = -1;
303 }
304 std::cout <<"mapping_last_size = "<< mapping_last << std::endl;
305
306 }
307
308 for (uint i = 0; i < host_vertices.size(); ++i) {
309 output << "v " << host_vertices[i][0] << " " << host_vertices[i][1] << " " << host_vertices[i][2] << std::endl;
310 outputF << "v " << host_vertices[i][0] << " " << host_vertices[i][1] << " " << host_vertices[i][2] << std::endl;
311 }
312
313 for (uint i = 0; i < vnList.size(); ++i) {
314 output << "vt " << vnList[i][0] << " " << vnList[i][1] << std::endl;
315 }
316
317 for (int i = 0; i < host_tri2tet.size(); ++i) {
318 Tri2Tet tmp = host_tri2tet[i];
319 bool isOnSurface = false;
320 if (tmp[0] < 0 || tmp[1] < 0) { isOnSurface = true; }
321 if (isOnSurface) {
322 Triangle newTri;
323
324 /*std::cout << 'a'
325 << host_VerId[host_triangles[i][0]] << ' '
326 << host_VerId[host_triangles[i][1]] <<' '
327 << host_VerId[host_triangles[i][2]] << std::endl;*/
328
329 newTri[0] = FaceMapping[host_VerId[host_triangles[i][0]]];
330 newTri[1] = FaceMapping[host_VerId[host_triangles[i][1]]];
331 newTri[2] = FaceMapping[host_VerId[host_triangles[i][2]]];
332 //std::cout << 'a' << std::endl;
333 int idInitSurface = onInitSurface(newTri);
334 //std::cout << idInitSurface << std::endl;
335 if (idInitSurface >= 0)
336 {
337 int newid1 = (newTri[0] == FaceId[idInitSurface].vertexId1) ? host_triangles[i][0] : ((newTri[1] == FaceId[idInitSurface].vertexId1) ? host_triangles[i][1] : host_triangles[i][2]);
338 int newid2 = (newTri[0] == FaceId[idInitSurface].vertexId2) ? host_triangles[i][0] : ((newTri[1] == FaceId[idInitSurface].vertexId2) ? host_triangles[i][1] : host_triangles[i][2]);
339 int newid3 = (newTri[0] == FaceId[idInitSurface].vertexId3) ? host_triangles[i][0] : ((newTri[1] == FaceId[idInitSurface].vertexId3) ? host_triangles[i][1] : host_triangles[i][2]);
340 output << "f "
341 << newid1 + 1 << "/" << FaceId[idInitSurface].uvId1 << " "
342 << newid2 + 1 << "/" << FaceId[idInitSurface].uvId2 << " "
343 << newid3 + 1 << "/" << FaceId[idInitSurface].uvId3 << std::endl;
344
345 }
346 else
347 {
348 int idx_vertex;
349 bool reverse = false;
350 int idx_tet = tmp[0] < 0 ? tmp[1] : tmp[0];
351 for (idx_vertex = 0; idx_vertex < 4; idx_vertex++)
352 {
353
354 if (host_tets[idx_tet][idx_vertex] != host_triangles[i][0]
355 && host_tets[idx_tet][idx_vertex] != host_triangles[i][1]
356 && host_tets[idx_tet][idx_vertex] != host_triangles[i][2]
357 )
358 break;
359 }
360 idx_vertex = host_tets[idx_tet][idx_vertex];
361 if (
362 ((host_vertices[host_triangles[i][1]] - host_vertices[host_triangles[i][0]]).cross
363 (host_vertices[host_triangles[i][2]] - host_vertices[host_triangles[i][1]]))
364 .dot
365 (host_vertices[idx_vertex] - host_vertices[host_triangles[i][0]]) > 0
366 )
367 reverse = true;
368 if (!reverse)
369 outputF << "f " << host_triangles[i][0] + 1 << " " << host_triangles[i][1] + 1 << " " << host_triangles[i][2] + 1 << std::endl;
370 else
371 outputF << "f " << host_triangles[i][0] + 1 << " " << host_triangles[i][2] + 1 << " " << host_triangles[i][1] + 1 << std::endl;
372
373 }
374 }
375
376 }
377
378 host_vertices.clear();
379 host_triangles.clear();
380 host_tri2tet.clear();
381 host_VerId.clear();
382
383 return true;
384 }
385
386
388}
#define DEFINE_CLASS(name)
Definition Object.h:140
#define IMPLEMENT_TCLASS(name, T1)
Definition Object.h:103
std::string constructFileName()
virtual void output()
std::shared_ptr< TetrahedronSet< TDataType > > ptr_TetrahedronSet
This is an implementation of AdditiveCCD based on peridyno.
Definition Array.h:25
DYN_FUNC Vector< T, 3 > cross(Vector< T, 3 > const &U, Vector< T, 3 > const &V)
Definition SimpleMath.h:211
DYN_FUNC T dot(Vector< T, 2 > const &U, Vector< T, 2 > const &V)
Definition SimpleMath.h:199
TopologyModule::Triangle Triangle
The standard summation density.
Array< T, DeviceType::CPU > CArray
Definition Array.h:151
unsigned int uint
Definition VkProgram.h:14
bool cmp(OriginalFaceId a, OriginalFaceId b)