1 // This file is part of libigl, a simple c++ geometry processing library.
2 //
3 // Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public License
6 // v. 2.0. If a copy of the MPL was not distributed with this file, You can
7 // obtain one at http://mozilla.org/MPL/2.0/.
8 #include "readTGF.h"
9
10 #include <cstdio>
11
readTGF(const std::string tgf_filename,std::vector<std::vector<double>> & C,std::vector<std::vector<int>> & E,std::vector<int> & P,std::vector<std::vector<int>> & BE,std::vector<std::vector<int>> & CE,std::vector<std::vector<int>> & PE)12 IGL_INLINE bool igl::readTGF(
13 const std::string tgf_filename,
14 std::vector<std::vector<double> > & C,
15 std::vector<std::vector<int> > & E,
16 std::vector<int> & P,
17 std::vector<std::vector<int> > & BE,
18 std::vector<std::vector<int> > & CE,
19 std::vector<std::vector<int> > & PE)
20 {
21 using namespace std;
22 // clear output
23 C.clear();
24 E.clear();
25 P.clear();
26 BE.clear();
27 CE.clear();
28 PE.clear();
29
30 FILE * tgf_file = fopen(tgf_filename.c_str(),"r");
31 if(NULL==tgf_file)
32 {
33 printf("IOError: %s could not be opened\n",tgf_filename.c_str());
34 return false;
35 }
36
37 bool reading_vertices = true;
38 bool reading_edges = true;
39 const int MAX_LINE_LENGTH = 500;
40 char line[MAX_LINE_LENGTH];
41 // read until seeing end of file
42 while(fgets(line,MAX_LINE_LENGTH,tgf_file)!=NULL)
43 {
44 // comment signifies end of vertices, next line is start of edges
45 if(line[0] == '#')
46 {
47 if(reading_vertices)
48 {
49 reading_vertices = false;
50 reading_edges = true;
51 }else if(reading_edges)
52 {
53 reading_edges = false;
54 }
55 // process vertex line
56 }else if(reading_vertices)
57 {
58 int index;
59 vector<double> position(3);
60 int count =
61 sscanf(line,"%d %lg %lg %lg",
62 &index,
63 &position[0],
64 &position[1],
65 &position[2]);
66 if(count != 4)
67 {
68 fprintf(stderr,"Error: readTGF.h: bad format in vertex line\n");
69 fclose(tgf_file);
70 return false;
71 }
72 // index is ignored since vertices must already be in order
73 C.push_back(position);
74 }else if(reading_edges)
75 {
76 vector<int> edge(2);
77 int is_BE = 0;
78 int is_PE = 0;
79 int is_CE = 0;
80 int count = sscanf(line,"%d %d %d %d %d\n",
81 &edge[0],
82 &edge[1],
83 &is_BE,
84 &is_PE,
85 &is_CE);
86 if(count<2)
87 {
88 fprintf(stderr,"Error: readTGF.h: bad format in edge line\n");
89 fclose(tgf_file);
90 return false;
91 }
92 // .tgf is one indexed
93 edge[0]--;
94 edge[1]--;
95 E.push_back(edge);
96 if(is_BE == 1)
97 {
98 BE.push_back(edge);
99 }
100 if(is_PE == 1)
101 {
102 // PE should index P
103 fprintf(stderr,
104 "Warning: readTGF.h found pseudo edges but does not support "
105 "them\n");
106 }
107 if(is_CE == 1)
108 {
109 // CE should index P
110 fprintf(stderr,
111 "Warning: readTGF.h found cage edges but does not support them\n");
112 }
113 }else
114 {
115 // ignore faces
116 }
117 }
118 fclose(tgf_file);
119 // Construct P, indices not in BE
120 for(int i = 0;i<(int)C.size();i++)
121 {
122 bool in_edge = false;
123 for(int j = 0;j<(int)BE.size();j++)
124 {
125 if(i == BE[j][0] || i == BE[j][1])
126 {
127 in_edge = true;
128 break;
129 }
130 }
131 if(!in_edge)
132 {
133 P.push_back(i);
134 }
135 }
136 return true;
137 }
138
139 #ifndef IGL_NO_EIGEN
140 #include "list_to_matrix.h"
141
readTGF(const std::string tgf_filename,Eigen::MatrixXd & C,Eigen::MatrixXi & E,Eigen::VectorXi & P,Eigen::MatrixXi & BE,Eigen::MatrixXi & CE,Eigen::MatrixXi & PE)142 IGL_INLINE bool igl::readTGF(
143 const std::string tgf_filename,
144 Eigen::MatrixXd & C,
145 Eigen::MatrixXi & E,
146 Eigen::VectorXi & P,
147 Eigen::MatrixXi & BE,
148 Eigen::MatrixXi & CE,
149 Eigen::MatrixXi & PE)
150 {
151 std::vector<std::vector<double> > vC;
152 std::vector<std::vector<int> > vE;
153 std::vector<int> vP;
154 std::vector<std::vector<int> > vBE;
155 std::vector<std::vector<int> > vCE;
156 std::vector<std::vector<int> > vPE;
157 bool success = readTGF(tgf_filename,vC,vE,vP,vBE,vCE,vPE);
158 if(!success)
159 {
160 return false;
161 }
162
163 if(!list_to_matrix(vC,C))
164 {
165 return false;
166 }
167 if(!list_to_matrix(vE,E))
168 {
169 return false;
170 }
171 if(!list_to_matrix(vP,P))
172 {
173 return false;
174 }
175 if(!list_to_matrix(vBE,BE))
176 {
177 return false;
178 }
179 if(!list_to_matrix(vCE,CE))
180 {
181 return false;
182 }
183 if(!list_to_matrix(vPE,PE))
184 {
185 return false;
186 }
187
188 return true;
189 }
190
readTGF(const std::string tgf_filename,Eigen::MatrixXd & C,Eigen::MatrixXi & E)191 IGL_INLINE bool igl::readTGF(
192 const std::string tgf_filename,
193 Eigen::MatrixXd & C,
194 Eigen::MatrixXi & E)
195 {
196 Eigen::VectorXi P;
197 Eigen::MatrixXi BE,CE,PE;
198 return readTGF(tgf_filename,C,E,P,BE,CE,PE);
199 }
200 #endif
201