Branch data Line data Source code
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 : : #include "ReadOBJ.hpp"
17 : : #include <iostream>
18 : : #include <sstream>
19 : : #include <fstream>
20 : : #include <vector>
21 : : #include <cstdlib>
22 : : #include <map>
23 : : #include <assert.h>
24 : : #include <cmath>
25 : :
26 : : #include "moab/Core.hpp"
27 : : #include "moab/Interface.hpp"
28 : : #include "moab/ReadUtilIface.hpp"
29 : : #include "Internals.hpp"
30 : : #include "moab/Range.hpp"
31 : : #include "moab/CartVect.hpp"
32 : : #include "moab/FileOptions.hpp"
33 : : #include "FileTokenizer.hpp"
34 : : #include "MBTagConventions.hpp"
35 : : #include "moab/CN.hpp"
36 : : #include "moab/GeomTopoTool.hpp"
37 : :
38 : : namespace moab
39 : : {
40 : :
41 : 1 : ReaderIface* ReadOBJ::factory( Interface* iface )
42 : : {
43 [ + - ]: 1 : return new ReadOBJ( iface );
44 : : }
45 : :
46 : : // Subset of starting tokens currently supported
47 : : const char* ReadOBJ::delimiters = " ";
48 : : const char* object_start_token = "o";
49 : : const char* group_start_token = "g";
50 : : const char* vertex_start_token = "v";
51 : : const char* face_start_token = "f";
52 : :
53 : : #define OBJ_AMBIGUOUS "AMBIGUOUS"
54 : : #define OBJ_UNDEFINED "UNDEFINED"
55 : :
56 : : // Name of geometric entities
57 : : const char* const geom_name[] = { "Vertex\0", "Curve\0", "Surface\0", "Volume\0" };
58 : :
59 : : // Geometric Categories
60 : : const char geom_category[][CATEGORY_TAG_SIZE] = { "Vertex\0", "Curve\0", "Surface\0", "Volume\0", "Group\0" };
61 : :
62 : : // Constructor
63 : 1 : ReadOBJ::ReadOBJ( Interface* impl )
64 : : : MBI( impl ), geom_tag( 0 ), id_tag( 0 ), name_tag( 0 ), category_tag( 0 ), faceting_tol_tag( 0 ),
65 : 1 : geometry_resabs_tag( 0 ), obj_name_tag( 0 )
66 : : {
67 [ - + ]: 1 : assert( NULL != impl );
68 [ + - ]: 1 : MBI->query_interface( readMeshIface );
69 [ + - ][ + - ]: 1 : myGeomTool = new GeomTopoTool( impl );
70 [ - + ]: 1 : assert( NULL != readMeshIface );
71 : :
72 : : // Get all handles
73 : 1 : int negone = -1;
74 : : ErrorCode rval;
75 : : rval = MBI->tag_get_handle( GEOM_DIMENSION_TAG_NAME, 1, MB_TYPE_INTEGER, geom_tag, MB_TAG_SPARSE | MB_TAG_CREAT,
76 [ + - ][ - + ]: 2 : &negone );MB_CHK_ERR_RET( rval );
[ # # ][ # # ]
77 : :
78 [ + - ]: 1 : id_tag = MBI->globalId_tag();
79 : :
80 [ + - ][ - + ]: 1 : rval = MBI->tag_get_handle( NAME_TAG_NAME, NAME_TAG_SIZE, MB_TYPE_OPAQUE, name_tag, MB_TAG_SPARSE | MB_TAG_CREAT );MB_CHK_ERR_RET( rval );
[ # # ][ # # ]
81 : :
82 : : rval = MBI->tag_get_handle( CATEGORY_TAG_NAME, CATEGORY_TAG_SIZE, MB_TYPE_OPAQUE, category_tag,
83 [ + - ][ - + ]: 1 : MB_TAG_SPARSE | MB_TAG_CREAT );MB_CHK_ERR_RET( rval );
[ # # ][ # # ]
84 : :
85 [ + - ][ - + ]: 1 : rval = MBI->tag_get_handle( "OBJECT_NAME", 32, MB_TYPE_OPAQUE, obj_name_tag, MB_TAG_SPARSE | MB_TAG_CREAT );MB_CHK_ERR_RET( rval );
[ # # ][ # # ]
86 : :
87 [ + - ][ - + ]: 1 : rval = MBI->tag_get_handle( "FACETING_TOL", 1, MB_TYPE_DOUBLE, faceting_tol_tag, MB_TAG_SPARSE | MB_TAG_CREAT );MB_CHK_ERR_RET( rval );
[ # # ][ # # ]
88 : :
89 : : rval =
90 [ + - ][ - + ]: 1 : MBI->tag_get_handle( "GEOMETRY_RESABS", 1, MB_TYPE_DOUBLE, geometry_resabs_tag, MB_TAG_SPARSE | MB_TAG_CREAT );MB_CHK_ERR_RET( rval );
[ # # ][ # # ]
91 : : }
92 : :
93 : : // Destructor
94 : 3 : ReadOBJ::~ReadOBJ()
95 : : {
96 [ + - ]: 1 : if( readMeshIface )
97 : : {
98 : 1 : MBI->release_interface( readMeshIface );
99 : 1 : readMeshIface = 0;
100 : : }
101 : :
102 [ + - ]: 1 : delete myGeomTool;
103 [ - + ]: 2 : }
104 : :
105 : 0 : ErrorCode ReadOBJ::read_tag_values( const char* /*file_name*/, const char* /*tag_name*/, const FileOptions& /*opts*/,
106 : : std::vector< int >& /*tag_values_out*/, const SubsetList* /*subset_list*/ )
107 : : {
108 : 0 : return MB_NOT_IMPLEMENTED;
109 : : }
110 : :
111 : : // Load the file as called by the Interface function
112 : 1 : ErrorCode ReadOBJ::load_file( const char* filename, const EntityHandle*, const FileOptions&,
113 : : const ReaderIface::SubsetList* subset_list, const Tag* /*file_id_tag*/ )
114 : : {
115 : : ErrorCode rval;
116 : 1 : int ignored = 0; // Number of lines not beginning with o, v, or f
117 [ + - ]: 1 : std::string line; // The current line being read
118 : : EntityHandle vert_meshset;
119 : : EntityHandle curr_meshset; // Current object meshset
120 [ + - ]: 2 : std::string object_name;
121 [ + - ]: 2 : std::vector< EntityHandle > vertex_list;
122 : 1 : int object_id = 0, group_id = 0; // ID number for each volume/surface
123 : : int num_groups;
124 : :
125 : : // At this time, there is no support for reading a subset of the file
126 [ - + ][ # # ]: 1 : if( subset_list ) { MB_SET_ERR( MB_UNSUPPORTED_OPERATION, "Reading subset of files not supported for OBJ." ); }
[ # # ][ # # ]
[ # # ][ # # ]
127 : :
128 [ + - ]: 2 : std::ifstream input_file( filename ); // Filestream for OBJ file
129 : :
130 : : // Check that the file can be read
131 [ + - ][ - + ]: 1 : if( !input_file.good() )
132 : : {
133 [ # # ][ # # ]: 0 : std::cout << "Problems reading file = " << filename << std::endl;
[ # # ]
134 : 0 : return MB_FILE_DOES_NOT_EXIST;
135 : : }
136 : :
137 : : // If the file can be read
138 [ + - ][ + - ]: 1 : if( input_file.is_open() )
139 : : {
140 : :
141 : : // create meshset for global vertices
142 [ + - ][ - + ]: 1 : rval = MBI->create_meshset( MESHSET_SET, vert_meshset );MB_CHK_SET_ERR( rval, "Failed to create global vert meshset." );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
143 : :
144 [ + - ][ + - ]: 1 : while( std::getline( input_file, line ) )
[ + - ]
145 : : {
146 : : // Skip blank lines in file
147 [ - + ]: 2 : if( line.length() == 0 ) continue;
148 : :
149 : : // Tokenize the line
150 [ + - ]: 1 : std::vector< std::string > tokens;
151 [ + - ]: 1 : tokenize( line, tokens, delimiters );
152 : :
153 : : // Each group and object line must have a name, token size is at least 2
154 : : // Each vertex and face line should have token size of at least 4
155 [ - + ]: 1 : if( tokens.size() < 2 ) continue;
156 : :
157 [ + - ][ + - ]: 1 : switch( get_keyword( tokens ) )
[ - - - -
- + ]
158 : : {
159 : : // Object line
160 : : case object_start: {
161 : 0 : object_id++;
162 [ # # ][ # # ]: 0 : object_name = tokens[1]; // Get name of object
163 : :
164 : : // Create new meshset for object
165 [ # # ][ # # ]: 0 : rval = create_new_object( object_name, object_id, curr_meshset );MB_CHK_ERR( rval );
[ # # ][ # # ]
[ # # ]
166 : 0 : break;
167 : : }
168 : :
169 : : // Group line
170 : : case group_start: {
171 : 0 : group_id++;
172 : 0 : num_groups = tokens.size() - 1;
173 [ # # ]: 0 : std::string group_name = "Group";
174 [ # # ]: 0 : for( int i = 0; i < num_groups; i++ )
175 : : {
176 [ # # ][ # # ]: 0 : group_name = group_name + '_' + tokens[i + 1];
[ # # ][ # # ]
177 : : }
178 : :
179 : : // Create new meshset for group
180 [ # # ][ # # ]: 0 : rval = create_new_group( group_name, group_id, curr_meshset );MB_CHK_ERR( rval );
[ # # ][ # # ]
[ # # ]
181 [ # # ]: 0 : break;
182 : : }
183 : :
184 : : // Vertex line
185 : : case vertex_start: {
186 : : // Read vertex and return EH
187 : : EntityHandle new_vertex_eh;
188 [ # # ][ # # ]: 0 : rval = create_new_vertex( tokens, new_vertex_eh );MB_CHK_ERR( rval );
[ # # ][ # # ]
[ # # ]
189 : :
190 : : // Add new vertex EH to list
191 [ # # ]: 0 : vertex_list.push_back( new_vertex_eh );
192 : :
193 : : // Add new vertex EH to the meshset
194 [ # # ][ # # ]: 0 : MBI->add_entities( vert_meshset, &new_vertex_eh, 1 );MB_CHK_SET_ERR( rval, "Failed to add vertex to global meshset." );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
195 : 0 : break;
196 : : }
197 : :
198 : : // Face line
199 : : case face_start: {
200 : : // Faces in .obj file can have 2, 3, or 4 vertices. If the face has
201 : : // 3 vertices, the EH will be immediately added to the meshset.
202 : : // If 4, face is split into triangles. Anything else is ignored.
203 : : EntityHandle new_face_eh;
204 : :
205 [ # # ]: 0 : if( tokens.size() == 4 )
206 : : {
207 [ # # ][ # # ]: 0 : rval = create_new_face( tokens, vertex_list, new_face_eh );MB_CHK_ERR( rval );
[ # # ][ # # ]
[ # # ]
208 : :
209 [ # # ]: 0 : if( rval == MB_SUCCESS )
210 : : {
211 : : // Add new face EH to the meshset
212 [ # # ]: 0 : MBI->add_entities( curr_meshset, &new_face_eh, 1 );
213 : : }
214 : : }
215 : :
216 [ # # ]: 0 : else if( tokens.size() == 5 )
217 : : {
218 : : // Split_quad fxn will create 2 new triangles from 1 quad
219 [ # # ]: 0 : Range new_faces_eh;
220 [ # # ][ # # ]: 0 : rval = split_quad( tokens, vertex_list, new_faces_eh );MB_CHK_ERR( rval );
[ # # ][ # # ]
[ # # ]
221 : :
222 : : // Add new faces created by split quad to meshset
223 [ # # ][ # # ]: 0 : if( rval == MB_SUCCESS ) { MBI->add_entities( curr_meshset, new_faces_eh ); }
[ # # ]
224 : : }
225 : :
226 : : else
227 : : {
228 [ # # ][ # # ]: 0 : std::cout << "Neither tri nor a quad: " << line << std::endl;
[ # # ]
229 : : }
230 : :
231 : 0 : break;
232 : : }
233 : :
234 : : case valid_unsupported: {
235 : : // First token is not recognized as a supported character
236 : 0 : ++ignored;
237 : 0 : break;
238 : : }
239 : :
240 : : default: {
241 [ + - ][ + - ]: 1 : MB_SET_ERR( MB_FAILURE, "Invalid/unrecognized line" );
[ + - ][ - + ]
[ + - ]
[ - - + ]
242 : : }
243 : : }
244 : 0 : }
245 : : }
246 : :
247 : : // If no object lines are read (those beginning w/ 'o'), file is not obj type
248 [ # # ][ # # ]: 0 : if( object_id == 0 && group_id == 0 ) { MB_SET_ERR( MB_FAILURE, "This is not an obj file. " ); }
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
249 : :
250 [ # # ][ # # ]: 0 : std::cout << "There were " << ignored << " ignored lines in this file." << std::endl;
[ # # ][ # # ]
251 : :
252 [ # # ]: 0 : input_file.close();
253 : :
254 : 1 : return MB_SUCCESS;
255 : : }
256 : :
257 : : /* The tokenize function will split an input line
258 : : * into a vector of strings based upon the delimiter
259 : : */
260 : 1 : void ReadOBJ::tokenize( const std::string& str, std::vector< std::string >& tokens, const char* delimiters2 )
261 : : {
262 : 1 : tokens.clear();
263 : :
264 : 1 : std::string::size_type next_token_end, next_token_start = str.find_first_not_of( delimiters2, 0 );
265 : :
266 [ + + ]: 4 : while( std::string::npos != next_token_start )
267 : : {
268 : 3 : next_token_end = str.find_first_of( delimiters2, next_token_start );
269 [ + + ]: 3 : if( std::string::npos == next_token_end )
270 : : {
271 [ + - ]: 1 : tokens.push_back( str.substr( next_token_start ) );
272 : 1 : next_token_start = std::string::npos;
273 : : }
274 : : else
275 : : {
276 [ + - ]: 2 : tokens.push_back( str.substr( next_token_start, next_token_end - next_token_start ) );
277 : 2 : next_token_start = str.find_first_not_of( delimiters2, next_token_end );
278 : : }
279 : : }
280 : 1 : }
281 : :
282 : 1 : keyword_type ReadOBJ::get_keyword( std::vector< std::string > tokens )
283 : : {
284 [ + - ]: 1 : std::map< std::string, keyword_type > keywords;
285 : :
286 : : // currently supported
287 [ + - ][ + - ]: 1 : keywords["o"] = object_start;
288 [ + - ][ + - ]: 1 : keywords["g"] = group_start;
289 [ + - ][ + - ]: 1 : keywords["f"] = face_start;
290 [ + - ][ + - ]: 1 : keywords["v"] = vertex_start;
291 : :
292 : : // not currently supported, will be ignored
293 [ + - ][ + - ]: 1 : keywords["vn"] = valid_unsupported;
294 [ + - ][ + - ]: 1 : keywords["vt"] = valid_unsupported;
295 [ + - ][ + - ]: 1 : keywords["vp"] = valid_unsupported;
296 [ + - ][ + - ]: 1 : keywords["s"] = valid_unsupported;
297 [ + - ][ + - ]: 1 : keywords["mtllib"] = valid_unsupported;
298 [ + - ][ + - ]: 1 : keywords["usemtl"] = valid_unsupported;
299 [ + - ][ + - ]: 1 : keywords["#"] = valid_unsupported;
300 [ + - ][ + - ]: 1 : keywords["cstype"] = valid_unsupported;
301 [ + - ][ + - ]: 1 : keywords["deg"] = valid_unsupported;
302 [ + - ][ + - ]: 1 : keywords["bmat"] = valid_unsupported;
303 [ + - ][ + - ]: 1 : keywords["step"] = valid_unsupported;
304 [ + - ][ + - ]: 1 : keywords["p"] = valid_unsupported;
305 [ + - ][ + - ]: 1 : keywords["l"] = valid_unsupported;
306 [ + - ][ + - ]: 1 : keywords["curv"] = valid_unsupported;
307 [ + - ][ + - ]: 1 : keywords["curv2"] = valid_unsupported;
308 [ + - ][ + - ]: 1 : keywords["surf"] = valid_unsupported;
309 [ + - ][ + - ]: 1 : keywords["parm"] = valid_unsupported;
310 [ + - ][ + - ]: 1 : keywords["trim"] = valid_unsupported;
311 [ + - ][ + - ]: 1 : keywords["hole"] = valid_unsupported;
312 [ + - ][ + - ]: 1 : keywords["scrv"] = valid_unsupported;
313 [ + - ][ + - ]: 1 : keywords["sp"] = valid_unsupported;
314 [ + - ][ + - ]: 1 : keywords["end"] = valid_unsupported;
315 [ + - ][ + - ]: 1 : keywords["mg"] = valid_unsupported;
316 [ + - ][ + - ]: 1 : keywords["bevel"] = valid_unsupported;
317 [ + - ][ + - ]: 1 : keywords["c_interp"] = valid_unsupported;
318 [ + - ][ + - ]: 1 : keywords["d_interp"] = valid_unsupported;
319 [ + - ][ + - ]: 1 : keywords["lod"] = valid_unsupported;
320 [ + - ][ + - ]: 1 : keywords["shadow_obj"] = valid_unsupported;
321 [ + - ][ + - ]: 1 : keywords["trace_obj"] = valid_unsupported;
322 [ + - ][ + - ]: 1 : keywords["ctech"] = valid_unsupported;
323 [ + - ][ + - ]: 1 : keywords["stech"] = valid_unsupported;
324 : :
325 [ + - ][ + - ]: 1 : return keywords[match( tokens[0], keywords )];
[ + - ]
326 : : }
327 : :
328 : : template < typename T >
329 : 1 : std::string ReadOBJ::match( const std::string& token, std::map< std::string, T >& tokenList )
330 : : {
331 : : // Initialize with no match and obj_undefined as return string
332 [ + - ]: 1 : std::string best_match = OBJ_UNDEFINED;
333 : :
334 : : // Search the map
335 [ + - ][ + - ]: 36 : for( typename std::map< std::string, T >::iterator thisToken = tokenList.begin(); thisToken != tokenList.end();
[ + + ]
336 : : ++thisToken )
337 : : {
338 : : // If a perfect match break the loop (assume keyword list is unambiguous)
339 [ + - ][ + - ]: 35 : if( token == ( *thisToken ).first )
[ - + ]
340 : : {
341 [ # # ]: 0 : best_match = token;
342 : 0 : break;
343 : : }
344 : : }
345 : :
346 : : // Possible return values: OBJ_UNDEFINED, keyword from list
347 : 1 : return best_match;
348 : : }
349 : :
350 : : /*
351 : : * The create_new_object function starts a new meshset for each object
352 : : * that will contain all faces that make up the object.
353 : : */
354 : 0 : ErrorCode ReadOBJ::create_new_object( std::string object_name, int curr_object, EntityHandle& object_meshset )
355 : : {
356 : : ErrorCode rval;
357 : :
358 : : // Create meshset to store object
359 : : // This is also referred to as the surface meshset
360 [ # # ][ # # ]: 0 : rval = MBI->create_meshset( MESHSET_SET, object_meshset );MB_CHK_SET_ERR( rval, "Failed to generate object mesh set." );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
361 : :
362 : : // Set surface meshset tags
363 [ # # ][ # # ]: 0 : rval = MBI->tag_set_data( name_tag, &object_meshset, 1, object_name.c_str() );MB_CHK_SET_ERR( rval, "Failed to set mesh set name tag." );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
364 : :
365 [ # # ][ # # ]: 0 : rval = MBI->tag_set_data( id_tag, &object_meshset, 1, &( curr_object ) );MB_CHK_SET_ERR( rval, "Failed to set mesh set ID tag." );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
366 : :
367 : 0 : int dim = 2;
368 [ # # ][ # # ]: 0 : rval = MBI->tag_set_data( geom_tag, &object_meshset, 1, &( dim ) );MB_CHK_SET_ERR( rval, "Failed to set mesh set dim tag." );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
369 : :
370 [ # # ][ # # ]: 0 : rval = MBI->tag_set_data( category_tag, &object_meshset, 1, geom_category[2] );MB_CHK_SET_ERR( rval, "Failed to set mesh set category tag." );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
371 : :
372 : : /* Create volume entity set corresponding to surface
373 : : The volume meshset will have one child--
374 : : the meshset of the surface that bounds the object.
375 : : */
376 : : EntityHandle vol_meshset;
377 [ # # ][ # # ]: 0 : rval = MBI->create_meshset( MESHSET_SET, vol_meshset );MB_CHK_SET_ERR( rval, "Failed to create volume mesh set." );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
378 : :
379 [ # # ][ # # ]: 0 : rval = MBI->add_parent_child( vol_meshset, object_meshset );MB_CHK_SET_ERR( rval, "Failed to add object mesh set as child of volume mesh set." );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
380 : :
381 : : /* Set volume meshset tags
382 : : The volume meshset is tagged with the same name as the surface meshset
383 : : for each object because of the direct relation between these entities.
384 : : */
385 [ # # ][ # # ]: 0 : rval = MBI->tag_set_data( obj_name_tag, &vol_meshset, 1, object_name.c_str() );MB_CHK_SET_ERR( rval, "Failed to set mesh set name tag." );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
386 : :
387 [ # # ][ # # ]: 0 : rval = MBI->tag_set_data( id_tag, &vol_meshset, 1, &( curr_object ) );MB_CHK_SET_ERR( rval, "Failed to set mesh set ID tag." );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
388 : :
389 : 0 : dim = 3;
390 [ # # ][ # # ]: 0 : rval = MBI->tag_set_data( geom_tag, &vol_meshset, 1, &( dim ) );MB_CHK_SET_ERR( rval, "Failed to set mesh set dim tag." );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
391 : :
392 [ # # ][ # # ]: 0 : rval = MBI->tag_set_data( name_tag, &vol_meshset, 1, geom_name[3] );MB_CHK_SET_ERR( rval, "Failed to set mesh set name tag." );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
393 : :
394 [ # # ][ # # ]: 0 : rval = MBI->tag_set_data( category_tag, &vol_meshset, 1, geom_category[3] );MB_CHK_SET_ERR( rval, "Failed to set mesh set category tag." );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
395 : :
396 [ # # ][ # # ]: 0 : rval = myGeomTool->set_sense( object_meshset, vol_meshset, SENSE_FORWARD );MB_CHK_SET_ERR( rval, "Failed to set surface sense." );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
397 : :
398 : 0 : return rval;
399 : : }
400 : :
401 : : /*
402 : : * The create_new_group function starts a new meshset for each group
403 : : * that will contain all faces that make up the group
404 : : */
405 : 0 : ErrorCode ReadOBJ::create_new_group( std::string group_name, int curr_group, EntityHandle& group_meshset )
406 : : {
407 : : ErrorCode rval;
408 : :
409 : : // Create meshset to store group
410 [ # # ][ # # ]: 0 : rval = MBI->create_meshset( MESHSET_SET, group_meshset );MB_CHK_SET_ERR( rval, "Failed to generate group mesh set." );
[ # # ][ # # ]
[ # # ][ # # ]
411 : :
412 : : // Set meshset tags
413 [ # # ][ # # ]: 0 : rval = MBI->tag_set_data( name_tag, &group_meshset, 1, group_name.c_str() );MB_CHK_SET_ERR( rval, "Failed to set mesh set name tag." );
[ # # ][ # # ]
[ # # ][ # # ]
414 : :
415 [ # # ][ # # ]: 0 : rval = MBI->tag_set_data( id_tag, &group_meshset, 1, &( curr_group ) );MB_CHK_SET_ERR( rval, "Failed to set mesh set ID tag." );
[ # # ][ # # ]
[ # # ][ # # ]
416 : :
417 : 0 : return rval;
418 : : }
419 : :
420 : : /* The create_new_vertex function converts a vector
421 : : of tokens (v x y z) to
422 : : the vertex format; a structure that has the three
423 : : coordinates as members.
424 : : */
425 : 0 : ErrorCode ReadOBJ::create_new_vertex( std::vector< std::string > v_tokens, EntityHandle& vertex_eh )
426 : : {
427 : : ErrorCode rval;
428 : : vertex next_vertex;
429 : :
430 [ # # ]: 0 : for( int i = 1; i < 4; i++ )
431 [ # # ]: 0 : next_vertex.coord[i - 1] = atof( v_tokens[i].c_str() );
432 : :
433 [ # # ][ # # ]: 0 : rval = MBI->create_vertex( next_vertex.coord, vertex_eh );MB_CHK_SET_ERR( rval, "Unbale to create vertex." );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
434 : :
435 : 0 : return rval;
436 : : }
437 : :
438 : : /* The create_new_face function converts a vector
439 : : of tokens ( f v1 v2 v3) ) to the face format;
440 : : a structure that has the three
441 : : connectivity points as members.
442 : : */
443 : 0 : ErrorCode ReadOBJ::create_new_face( std::vector< std::string > f_tokens, const std::vector< EntityHandle >& vertex_list,
444 : : EntityHandle& face_eh )
445 : : {
446 : : face next_face;
447 : : ErrorCode rval;
448 : :
449 [ # # ]: 0 : for( int i = 1; i < 4; i++ )
450 : : {
451 [ # # ]: 0 : int vertex_id = atoi( f_tokens[i].c_str() );
452 : :
453 : : // Some faces contain format 'vertex/texture'
454 : : // Remove the '/texture' and add the vertex to the list
455 [ # # ]: 0 : std::size_t slash = f_tokens[i].find( '/' );
456 [ # # ]: 0 : if( slash != std::string::npos )
457 : : {
458 [ # # ][ # # ]: 0 : std::string face = f_tokens[i].substr( 0, slash );
459 : 0 : vertex_id = atoi( face.c_str() );
460 : : }
461 : :
462 [ # # ]: 0 : next_face.conn[i - 1] = vertex_list[vertex_id - 1];
463 : : }
464 : :
465 [ # # ][ # # ]: 0 : rval = MBI->create_element( MBTRI, next_face.conn, 3, face_eh );MB_CHK_SET_ERR( rval, "Unable to create new face." );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
466 : :
467 : 0 : return rval;
468 : : }
469 : :
470 : : // The split_quad function divides a quad face into 4 tri faces.
471 : 0 : ErrorCode ReadOBJ::split_quad( std::vector< std::string > f_tokens, std::vector< EntityHandle >& vertex_list,
472 : : Range& face_eh )
473 : : {
474 : : ErrorCode rval;
475 [ # # ]: 0 : std::vector< EntityHandle > quad_vert_eh;
476 : :
477 : : // Loop over quad connectivity getting vertex EHs
478 [ # # ]: 0 : for( int i = 1; i < 5; i++ )
479 : : {
480 [ # # ]: 0 : int vertex_id = atoi( f_tokens[i].c_str() );
481 [ # # ]: 0 : std::size_t slash = f_tokens[i].find( '/' );
482 [ # # ]: 0 : if( slash != std::string::npos )
483 : : {
484 [ # # ][ # # ]: 0 : std::string face = f_tokens[i].substr( 0, slash );
485 : 0 : vertex_id = atoi( face.c_str() );
486 : : }
487 : :
488 [ # # ][ # # ]: 0 : quad_vert_eh.push_back( vertex_list[vertex_id - 1] );
489 : : }
490 : :
491 : : // Create new tri faces
492 [ # # ][ # # ]: 0 : rval = create_tri_faces( quad_vert_eh, face_eh );MB_CHK_SET_ERR( rval, "Failed to create triangles when splitting quad." );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
493 : :
494 : 0 : return rval;
495 : : }
496 : :
497 : 0 : ErrorCode ReadOBJ::create_tri_faces( std::vector< EntityHandle > quad_vert_eh,
498 : : // EntityHandle center_vertex_eh,
499 : : Range& face_eh )
500 : : {
501 : : ErrorCode rval;
502 : : EntityHandle connectivity[3];
503 : : EntityHandle new_face;
504 : :
505 [ # # ]: 0 : connectivity[0] = quad_vert_eh[0];
506 [ # # ]: 0 : connectivity[1] = quad_vert_eh[1];
507 [ # # ]: 0 : connectivity[2] = quad_vert_eh[2];
508 [ # # ]: 0 : rval = MBI->create_element( MBTRI, connectivity, 3, new_face );
509 [ # # ]: 0 : face_eh.insert( new_face );
510 : :
511 [ # # ]: 0 : connectivity[0] = quad_vert_eh[2];
512 [ # # ]: 0 : connectivity[1] = quad_vert_eh[3];
513 [ # # ]: 0 : connectivity[2] = quad_vert_eh[0];
514 [ # # ]: 0 : rval = MBI->create_element( MBTRI, connectivity, 3, new_face );
515 [ # # ]: 0 : face_eh.insert( new_face );
516 : :
517 : 0 : return rval;
518 : : }
519 : :
520 [ + - ][ + - ]: 228 : } // namespace moab
|