Branch data Line data Source code
1 : : /**
2 : : * \class ReadTemplate
3 : : * \brief Template for writing a new reader in MOAB
4 : : *
5 : : */
6 : :
7 : : #include "ReadTemplate.hpp"
8 : : #include "moab/Interface.hpp"
9 : : #include "moab/ReadUtilIface.hpp"
10 : : #include "moab/Range.hpp"
11 : : #include "moab/FileOptions.hpp"
12 : :
13 : : #include <cstdio>
14 : : #include <assert.h>
15 : :
16 : : namespace moab
17 : : {
18 : :
19 : 1 : ReaderIface* ReadTemplate::factory( Interface* iface )
20 : : {
21 [ + - ]: 1 : return new ReadTemplate( iface );
22 : : }
23 : :
24 : 2 : ReadTemplate::ReadTemplate( Interface* impl ) : mbImpl( impl ), fileName( NULL )
25 : : {
26 [ + - ]: 1 : mbImpl->query_interface( readMeshIface );
27 : 1 : }
28 : :
29 : 3 : ReadTemplate::~ReadTemplate()
30 : : {
31 [ + - ]: 1 : if( readMeshIface )
32 : : {
33 : 1 : mbImpl->release_interface( readMeshIface );
34 : 1 : readMeshIface = 0;
35 : : }
36 [ - + ]: 2 : }
37 : :
38 : 0 : ErrorCode ReadTemplate::read_tag_values( const char* /* file_name */, const char* /* tag_name */,
39 : : const FileOptions& /* opts */, std::vector< int >& /* tag_values_out */,
40 : : const SubsetList* /* subset_list */ )
41 : : {
42 : 0 : return MB_NOT_IMPLEMENTED;
43 : : }
44 : :
45 : 2 : ErrorCode ReadTemplate::load_file( const char* filename, const EntityHandle* file_set, const FileOptions& opts,
46 : : const ReaderIface::SubsetList* subset_list, const Tag* /*file_id_tag*/ )
47 : : {
48 : : if( subset_list )
49 : : {
50 : : // See src/moab/ReaderIface.hpp, definition of SubsetList struct; this basically specifies
51 : : // an integer tag and tag values for sets to read on this proc, or a part number and total #
52 : : // parts for reading a trivial partition of entities
53 : : }
54 : :
55 : : // Save filename to member variable so we don't need to pass as an argument
56 : : // to called functions
57 : 1 : fileName = filename;
58 : :
59 : : // Process options; see src/FileOptions.hpp for API for FileOptions class, and
60 : : // doc/metadata_info.doc for a description of various options used by some of the readers in
61 : : // MOAB
62 [ + - ][ - + ]: 1 : ErrorCode result = process_options( opts );MB_CHK_SET_ERR( result, fileName << ": problem reading options" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
63 : :
64 : : // Open file; filePtr is member of ReadTemplate, change to whatever mechanism is used to
65 : : // identify file
66 [ + - ]: 1 : FILE* filePtr = fopen( fileName, "r" );
67 [ - + ][ # # ]: 1 : if( !filePtr ) { MB_SET_ERR( MB_FILE_DOES_NOT_EXIST, fileName << ": fopen returned error" ); }
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
68 : :
69 : : // Read number of verts, elements, sets
70 : 1 : long num_verts = 0, num_elems = 0, num_sets = 0;
71 : :
72 : : // read_ents keeps a running set of entities read from this file, including vertices, elements,
73 : : // and sets; these will get added to file_set (if input) at the end of the read
74 [ + - ]: 1 : Range read_ents;
75 : :
76 : : // start_vertex is passed back so we know how to convert indices from the file into vertex
77 : : // handles; most of the time this is done by adding start_vertex to the (0-based) index; if the
78 : : // index is 1-based, you also need to subtract one; see read_elements for details
79 : : EntityHandle start_vertex;
80 [ + - ]: 1 : result = read_vertices( num_verts, start_vertex, read_ents );
81 [ + - ]: 1 : if( MB_SUCCESS != result )
82 : : {
83 [ + - ]: 1 : fclose( filePtr );
84 : 1 : return result;
85 : : }
86 : :
87 : : // Create/read elements; this template assumes that all elements are the same type, so can be
88 : : // read in a single call to read_elements, and kept track of with a single start_elem handle. If
89 : : // there are more entity types, might have to keep these start handles in an array/vector.
90 : : // start_elem is only really needed if you're reading sets later, and need to convert some
91 : : // file-based index to an entity handle
92 : : EntityHandle start_elem;
93 [ # # ]: 0 : result = read_elements( num_elems, start_vertex, start_elem, read_ents );
94 [ # # ]: 0 : if( MB_SUCCESS != result )
95 : : {
96 [ # # ]: 0 : fclose( filePtr );
97 : 0 : return result;
98 : : }
99 : :
100 : : // Read/create entity sets; typically these sets have some tag identifying what they're for, see
101 : : // doc/metadata_info.doc for examples of different kinds of sets and how they're marked
102 [ # # ]: 0 : result = create_sets( num_sets, start_vertex, num_verts, start_elem, num_elems, read_ents );
103 [ # # ]: 0 : if( MB_SUCCESS != result )
104 : : {
105 [ # # ]: 0 : fclose( filePtr );
106 : 0 : return result;
107 : : }
108 : :
109 : : // Finally, add all read_ents into the file set, if one was input
110 [ # # ][ # # ]: 0 : if( file_set && *file_set )
111 : : {
112 [ # # ]: 0 : result = mbImpl->add_entities( *file_set, read_ents );
113 [ # # ]: 0 : if( MB_SUCCESS != result )
114 : : {
115 [ # # ]: 0 : fclose( filePtr );
116 : 0 : return result;
117 : : }
118 : : }
119 : :
120 [ # # ]: 0 : fclose( filePtr );
121 : :
122 : 1 : return result;
123 : : }
124 : :
125 : 1 : ErrorCode ReadTemplate::read_vertices( int num_verts, EntityHandle& start_vertex, Range& read_ents )
126 : : {
127 : : // Allocate nodes; these are allocated in one shot, get contiguous handles starting with
128 : : // start_handle, and the reader is passed back double*'s pointing to MOAB's native storage for
129 : : // vertex coordinates for those verts
130 [ + - ]: 1 : std::vector< double* > coord_arrays;
131 [ + - ][ + - ]: 1 : ErrorCode result = readMeshIface->get_node_coords( 3, num_verts, 1, start_vertex, coord_arrays );MB_CHK_SET_ERR( result, fileName << ": Trouble reading vertices" );
[ + - ][ + - ]
[ + - ][ + - ]
[ - + ][ + - ]
132 : :
133 : : // Fill in vertex coordinate arrays
134 [ # # ][ # # ]: 0 : double *x = coord_arrays[0], *y = coord_arrays[1], *z = coord_arrays[2];
[ # # ]
135 [ # # ]: 0 : for( long i = 0; i < num_verts; ++i )
136 : : {
137 : : // Read x/y/z; do something with them for now to avoid warning
138 : : if( x || y || z ) {}
139 : : }
140 : :
141 [ # # ][ # # ]: 0 : if( num_verts ) read_ents.insert( start_vertex, start_vertex + num_verts - 1 );
142 : :
143 : 1 : return result;
144 : : }
145 : :
146 : : //! Read/create elements
147 : 0 : ErrorCode ReadTemplate::read_elements( int num_elems, EntityHandle start_vertex, EntityHandle& start_elem,
148 : : Range& read_ents )
149 : : {
150 : : // Get the entity type being read
151 : 0 : EntityType ent_type = MBHEX;
152 : :
153 : : // Get the number of vertices per entity
154 : 0 : int verts_per_elem = 8;
155 : :
156 : : // Create the element sequence; passes back a pointer to the internal storage for connectivity
157 : : // and the starting entity handle
158 : : EntityHandle* conn_array;
159 : : ErrorCode result =
160 [ # # ][ # # ]: 0 : readMeshIface->get_element_connect( num_elems, verts_per_elem, ent_type, 1, start_elem, conn_array );MB_CHK_SET_ERR( result, fileName << ": Trouble reading elements" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
161 : :
162 : : // Read connectivity into conn_array directly
163 [ # # ]: 0 : for( long i = 0; i < num_elems; i++ )
164 : : {
165 : : // Read connectivity
166 : : }
167 : :
168 : : // Convert file-based connectivity indices to vertex handles in-place; be careful, if indices
169 : : // are smaller than handles, need to do from the end of the list so we don't overwrite data
170 : : //
171 : : // Here, we assume indices are smaller than handles, just for demonstration; create an
172 : : // integer-type pointer to connectivity initialized to same start of connectivity array
173 : 0 : int* ind_array = reinterpret_cast< int* >( conn_array );
174 : : // OFFSET is value of first vertex index in file; most files are 1-based, but some might be
175 : : // 0-based
176 : 0 : int OFFSET = 1;
177 [ # # ]: 0 : for( long i = num_elems * verts_per_elem - 1; i >= 0; i-- )
178 : : {
179 : 0 : conn_array[i] = ind_array[i] + start_vertex + OFFSET;
180 : :
181 : : // This assert assumes last handle in read_ents is highest vertex handle in this file
182 [ # # ][ # # ]: 0 : assert( conn_array[i] >= start_vertex && conn_array[i] <= *read_ents.rbegin() );
[ # # ][ # # ]
[ # # ][ # # ]
183 : : }
184 : :
185 : : // Notify MOAB of the new elements
186 [ # # ]: 0 : result = readMeshIface->update_adjacencies( start_elem, num_elems, verts_per_elem, conn_array );
187 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
188 : :
189 : : // Add elements to read_ents
190 [ # # ][ # # ]: 0 : if( num_elems ) read_ents.insert( start_elem, start_elem + num_elems - 1 );
191 : :
192 : 0 : return MB_SUCCESS;
193 : : }
194 : :
195 : : //! Read/create sets
196 : 0 : ErrorCode ReadTemplate::create_sets( int num_sets, EntityHandle /*start_vertex*/, int /*num_verts*/,
197 : : EntityHandle /*start_elem*/, int /*num_elems*/, Range& read_ents )
198 : : {
199 : 0 : ErrorCode result = MB_SUCCESS;
200 : : EntityHandle this_set;
201 : :
202 [ # # ]: 0 : for( int i = 0; i < num_sets; i++ )
203 : : {
204 : : // Create set
205 [ # # ][ # # ]: 0 : result = mbImpl->create_meshset( MESHSET_SET, this_set );MB_CHK_SET_ERR( result, fileName << ": Trouble creating set" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
206 : :
207 [ # # ]: 0 : Range set_ents;
208 : : // Read/compute what's in this set; REMEMBER TO CONVERT THESE TO MOAB HANDLES
209 : :
210 : : // Add them to the set
211 [ # # ][ # # ]: 0 : result = mbImpl->add_entities( this_set, set_ents );MB_CHK_SET_ERR( result, fileName << ": Trouble putting entities in set" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
212 : :
213 : : // Add the new set to read_ents
214 [ # # ][ # # ]: 0 : read_ents.insert( this_set );
215 : 0 : }
216 : :
217 : 0 : return MB_SUCCESS;
218 : : }
219 : :
220 : 1 : ErrorCode ReadTemplate::process_options( const FileOptions& opts )
221 : : {
222 : : // Mark all options seen, to avoid compile warning on unused variable
223 : 1 : opts.mark_all_seen();
224 : 1 : return MB_SUCCESS;
225 : : }
226 : :
227 [ + - ][ + - ]: 228 : } // namespace moab
|