Mesh Oriented datABase  (version 5.5.0)
An array-based unstructured mesh library
ReadOBJ.hpp
Go to the documentation of this file.
1 /**
2  * MOAB, a Mesh-Oriented datABase, is a software component for creating,
3  * storing and accessing finite element mesh data.
4  *
5  * Copyright 2004 Sandia Corporation. Under the terms of Contract
6  * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
7  * retains certain rights in this software.
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  */
15 
16 //-----------------------------------------------------------------------------
17 // Filename : ReadOBJ.hpp
18 //
19 // Purpose : Wavefront obj file reader
20 //
21 // Creators : Chelsea D'Angelo, Paul Wilson, Andrew Davis
22 //
23 // Date : 02/16
24 //
25 // Owner : Chelsea D'Angelo
26 //-----------------------------------------------------------------------------
27 
28 /**
29  * This class will read in an obj file and populate a MOAB instance with the
30  * vertex and connectivity information in the file. A specification for obj files
31  * can be found here: https://en.wikipedia.org/wiki/Wavefront_.obj_file
32  * This reader only supports a subset of the full file structure, namely,
33  * object names, group names, vertices, and faces.
34  *
35  * Overview of the supported structure:
36  *
37  * Heading
38  * Object line: o object_name
39  * Group line: g group_name1
40  * Vertex lines: v x y z
41  * Face lines (tri): f v1 v2 v3
42  * Face lines (quad): f v1 v2 v3 v4
43  *
44  * Lines that begin w/ anything other than 'o ', 'g ', 'v ', and 'f ' are not
45  * supported. If a valid, but unsupported line is found, it will be ignored.
46  * If an invalid line is found, an error will be produced.
47  * Face lines that contain 'vertex\texture\normal' are handled by ignoring the
48  * texture and normal
49  *
50  *
51  * A new meshset will be created for each object or group in the file.
52  * Each object and group must have a name, or the line will be ignored.
53  * Groups are thought to be collections of elements with no dimension or category and
54  * will therefore only be assigned name and id tags.
55  * Objects are thought to be closed surfaces. A surface meshset will be
56  * created for each object. A volume meshset that directly corresponds
57  * to the surface meshset will also be created. These will have name, id,
58  * categorty, and dimension tags. A parent-child relationship exists
59  * between the volume and surface meshsets.
60  * Vertices will be created and added to a global vertex meshset.
61  * Triangular faces will be created and added as members of the surface meshets.
62  */
63 
64 #ifndef READ_OBJ_HPP
65 #define READ_OBJ_HPP
66 
67 #ifndef IS_BUILDING_MB
68 #error "ReadOBJ.hpp isn't supposed to be included into an application"
69 #endif
70 
71 #include <iostream>
72 #include <fstream>
73 #include <sstream>
74 #include <vector>
75 #include <map>
76 
77 #include "moab/Interface.hpp"
78 #include "moab/ReaderIface.hpp"
79 #include "FileTokenizer.hpp"
80 #include "moab/RangeMap.hpp"
81 #include "MBTagConventions.hpp"
82 
83 /* struct vertex is a structure that stores coordinates
84  of vertices. This is a convenience structure making
85  i/o easier.
86 */
87 struct vertex
88 {
89  int vertex_id;
90  double coord[3];
91 };
92 
93 /* struct face is a structure that stores connectivity.
94  This is a convenience structure makin i/o easier.
95 */
96 struct face
97 {
98  int face_id;
100 };
101 namespace moab
102 {
103 
104 /* Supported obj file keywords
105  */
107 {
114 };
115 
116 class ReadUtilIface;
117 class GeomTopoTool;
118 
119 class ReadOBJ : public ReaderIface
120 {
121 
122  public:
123  //! factory method
124  static ReaderIface* factory( Interface* );
125 
126  ErrorCode load_file( const char* file_name,
127  const EntityHandle* file_set,
128  const FileOptions& opts,
129  const SubsetList* subset_list = 0,
130  const Tag* file_id_tag = 0 );
131 
132  ErrorCode read_tag_values( const char* file_name,
133  const char* tag_name,
134  const FileOptions& opts,
135  std::vector< int >& tag_values_out,
136  const SubsetList* subset_list = 0 );
137 
138  //! Constructor
139  ReadOBJ( Interface* impl = NULL );
140 
141  //! Destructor
142  virtual ~ReadOBJ();
143 
144  private:
146 
147  //! interface instance
149 
151 
153 
154  /* The keyword type function matches the first character extracted from each line to a type of
155  * line
156  */
157  keyword_type get_keyword( std::vector< std::string > tokens );
158 
159  /* The match function searches a list of map keys for a match with the token
160  */
161  template < typename T >
162  std::string match( const std::string& token, std::map< std::string, T >& tokenList );
163 
164  /* The tokenize function takes a string as input and splits it into
165  * a vector of strings based on the delimiter
166  */
167  static const char* delimiters;
168 
169  void tokenize( const std::string& str, std::vector< std::string >& tokens, const char* delimiters );
170 
171  /*
172  * The create_object funtion will create a new meshset for
173  * each object that contains all vertices and faces
174  */
175  ErrorCode create_new_object( std::string object_name, int object_id, EntityHandle& curr_obj_meshset );
176 
177  ErrorCode create_new_group( std::string object_name, int curr_object, EntityHandle& object_meshset );
178 
179  /* create_new_vertex converts tokenized string input to
180  vertex structure
181  */
182  ErrorCode create_new_vertex( std::vector< std::string > v_tokens, EntityHandle& vertex_eh );
183 
184  /* create_new_face converts tokenized string input to
185  * face structure
186  */
187  ErrorCode create_new_face( std::vector< std::string > f_tokens,
188  const std::vector< EntityHandle >& vertex_list,
189  EntityHandle& face_eh );
190 
191  /*
192  * The split_quad function creates 1 new vertex and 4 new tri faces
193  * from a quad face.
194  */
195 
196  ErrorCode split_quad( std::vector< std::string > f_tokens,
197  std::vector< EntityHandle >& vertex_list,
198  Range& face_eh );
199 
200  ErrorCode create_tri_faces( std::vector< EntityHandle > quad_vert_eh,
201  // EntityHandle center_vertex_eh,
202  Range& face_eh );
203 };
204 
205 } // namespace moab
206 
207 #endif