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