BRL-CAD
obj_parser_state.h
Go to the documentation of this file.
1 /* O B J _ P A R S E R _ S T A T E . H
2  * BRL-CAD
3  *
4  * Copyright (c) 2010-2014 United States Government as represented by
5  * the U.S. Army Research Laboratory.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * version 2.1 as published by the Free Software Foundation.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this file; see the file named COPYING for more
18  * information.
19  */
20 
21 #ifndef LIBGCV_WFOBJ_OBJ_PARSER_STATE_H
22 #define LIBGCV_WFOBJ_OBJ_PARSER_STATE_H
23 
24 #include "common.h"
25 
26 #include "obj_parser.h"
27 #include "bu/str.h"
28 
29 #include <memory>
30 #include <string>
31 #include <sstream>
32 #include <vector>
33 #include <set>
34 #include <map>
35 #include <algorithm>
36 #include <cstring>
37 
38 inline bool operator<(const obj_polygonal_attributes_t &lhs,
39  const obj_polygonal_attributes_t &rhs)
40 {
41  return std::memcmp(&lhs, &rhs, sizeof(obj_polygonal_attributes_t)) < 0;
42 }
43 
44 
45 namespace cad {
46 namespace gcv {
47 namespace obj {
48 
49 typedef void *parser_type;
50 
51 template<typename T, std::size_t N>
52 struct tuple {
53  T v[N];
54 };
55 
56 
57 /* recursive tuple comparison */
58 template<typename T, std::size_t N, std::size_t i>
59 struct tuple_compare {
60  bool compare(tuple<T, N> &lhs, const tuple<T, N> &rhs) {
61  return lhs[i] == rhs[i] && tuple_compare<T, N, i - 1>(lhs, rhs);
62  }
63 };
64 
65 /* tuple comparison base case */
66 template<typename T, std::size_t N>
67 struct tuple_compare<T, N, 0> {
68  void compare(tuple<T, N> &lhs, const tuple<T, N> &rhs) {
69  return lhs[0] == rhs[0];
70  }
71 };
72 
73 
74 template<typename T, std::size_t N>
75 inline bool operator==(const tuple<T, N> &lhs, const tuple<T, N> &rhs)
76 {
77  return tuple_compare<T, N, N>::compare(lhs, rhs);
78 }
79 
80 /**
81  * Basic parser object, persistent across multiple file parsings
82  *
83  * Lifetime is controlled by the user via obj_parser_create
84  * and obj_parser_destroy.
85  */
86 template<typename charT=char,
87  typename traits=std::char_traits<char>,
88  typename Allocator=std::allocator<char> >
90  typedef std::basic_string<charT, traits, Allocator> string_type;
91  // include paths etc.
92 
93  string_type last_error;
94 };
95 
96 /* contents of an obj file */
97 template<typename PrecisionT,
98  typename charT=char,
99  typename traits=std::char_traits<char>,
100  typename Allocator=std::allocator<char> >
102  typedef PrecisionT precision_type;
106 
107  typedef size_t polygonal_v_index_type;
111 
112  // indexloc_t := {start, length}
113  typedef std::pair<size_t, size_t> indexloc_t;
114  typedef std::vector<indexloc_t> indexloc_vec_type;
115 
116  typedef std::vector<size_t> indexvec_type;
117  typedef std::vector<indexvec_type> indexvec_vec_type;
118 
119  typedef std::vector<polygonal_v_index_type> polygonal_v_indexvec_type;
120  typedef std::vector<polygonal_tv_index_type> polygonal_tv_indexvec_type;
121  typedef std::vector<polygonal_nv_index_type> polygonal_nv_indexvec_type;
122  typedef std::vector<polygonal_tnv_index_type> polygonal_tnv_indexvec_type;
123 
124  typedef std::basic_string<charT, traits, Allocator> string_type;
125 
126  typedef std::vector<string_type> stringvec_type;
127  typedef std::vector<const charT *> charvec_type;
128 
129  typedef std::vector<obj_polygonal_attributes_t> polyattributes_vec_type;
130 
131  // all vertices
132  std::vector<gvertex_t> gvertices_list;
133  std::vector<nvertex_t> tvertices_list;
134  std::vector<tvertex_t> nvertices_list;
135 
136  // unordered set s.t. the default (possibly empty) value is first
137  // these are indexed in interface for space consideration
138  // The *char_set is just a vector of const char * from *_set[i].c_str()
139  stringvec_type group_set;
140  charvec_type groupchar_set;
141  indexvec_vec_type groupindex_set;
142 
143  stringvec_type object_set;
144  charvec_type objectchar_set;
145 
146  stringvec_type material_set;
147  charvec_type materialchar_set;
148 
149  stringvec_type materiallib_set;
150  charvec_type materiallibchar_set;
151  indexvec_vec_type materiallibindex_set;
152 
153  stringvec_type texmap_set;
154  charvec_type texmapchar_set;
155 
156  stringvec_type texmaplib_set;
157  charvec_type texmaplibchar_set;
158  indexvec_vec_type texmaplibindex_set;
159 
160  stringvec_type shadow_obj_set;
161  charvec_type shadow_objchar_set;
162 
163  stringvec_type trace_obj_set;
164  charvec_type trace_objchar_set;
165 
166  // unordered set of polygonal attributes
167  polyattributes_vec_type polyattributes_set;
168 
169  // point_*_attr_list is list of indices into polyattributes_set
170  // point_*_indexlist is a vector of n-tuples of indices
171  // point_*_attr_list and point_*_indexlist are synced
172  indexvec_type point_v_attr_list;
173  indexloc_vec_type point_v_loclist;
174  polygonal_v_indexvec_type point_v_indexlist;
175 
176  // line_*_attr_list is list of indices into polyattributes_set
177  // line_*_indexlist is a vector of n-tuples of indices
178  // line_*_attr_list and line_*_indexlist are synced
179  indexvec_type line_v_attr_list;
180  indexloc_vec_type line_v_loclist;
181  polygonal_v_indexvec_type line_v_indexlist;
182 
183  indexvec_type line_tv_attr_list;
184  indexloc_vec_type line_tv_loclist;
185  polygonal_tv_indexvec_type line_tv_indexlist;
186 
187  // polygonal_*_attr_list is list of indices into polyattributes_set
188  // pologonal_*_indexlist is a vector of n-tuples of indices
189  // polygonal_*_attr_list and pologonal_*_indexlist are synced
190  indexvec_type polygonal_v_attr_list;
191  indexloc_vec_type polygonal_v_loclist;
192  polygonal_v_indexvec_type pologonal_v_indexlist;
193 
194  indexvec_type polygonal_tv_attr_list;
195  indexloc_vec_type polygonal_tv_loclist;
196  polygonal_tv_indexvec_type pologonal_tv_indexlist;
197 
198  indexvec_type polygonal_nv_attr_list;
199  indexloc_vec_type polygonal_nv_loclist;
200  polygonal_nv_indexvec_type pologonal_nv_indexlist;
201 
202  indexvec_type polygonal_tnv_attr_list;
203  indexloc_vec_type polygonal_tnv_loclist;
204  polygonal_tnv_indexvec_type pologonal_tnv_indexlist;
205 }; /* basic_obj_contents */
206 
207 
208 template<typename ObjContentsT>
210  typedef ObjContentsT contents_type;
211  typedef typename contents_type::string_type string_type;
212 
213  typedef std::basic_stringstream<typename string_type::value_type,
214  typename string_type::traits_type,
215  typename string_type::allocator_type>
217 
218  typedef std::size_t index_type;
219 
223 
224  typedef typename contents_type::polygonal_v_indexvec_type
226 
227  typedef typename contents_type::polygonal_tv_indexvec_type
229 
230  typedef typename contents_type::polygonal_nv_indexvec_type
232 
233  typedef typename contents_type::polygonal_tnv_indexvec_type
235 
236  typedef typename contents_type::indexvec_type indexvec_type;
237  typedef typename contents_type::indexvec_vec_type indexvec_vec_type;
238  typedef typename indexvec_vec_type::size_type indexvec_vec_index_type;
239 
240  typedef std::set<string_type> stringset_type;
241  typedef typename contents_type::stringvec_type stringvec_type;
242  typedef typename contents_type::charvec_type charvec_type;
243  typedef typename stringvec_type::size_type stringvec_index_type;
244 
245  typedef std::map<string_type, typename charvec_type::size_type>
247 
248  typedef std::map<stringset_type, indexvec_vec_index_type>
250 
251  typedef std::map<string_type, stringvec_index_type>
253 
254  typedef std::map<string_type, stringvec_index_type>
256 
257  typedef std::map<stringset_type, indexvec_vec_index_type>
259 
260  typedef std::map<string_type, stringvec_index_type>
262 
263  typedef std::map<stringset_type, indexvec_vec_index_type>
265 
266  typedef std::map<string_type, stringvec_index_type>
268 
269  typedef std::map<string_type, stringvec_index_type>
271 
272  typedef typename contents_type::polyattributes_vec_type
274 
275  typedef typename polyattributes_vec_type::size_type
277 
278  typedef std::map<obj_polygonal_attributes_t, polyattributes_vec_index_type>
280 
281  struct file_node {
282  string_type path;
283  string_type dir;
284  std::size_t lineno;
285  FILE *file;
286  };
287 
288  std::vector<file_node> file_stack;
291 
292  /**
293  * Working contents for content construction during parse
294  */
295  string_type working_string;
296  stringset_type working_stringset;
298 
299  // index from strings to content group_set indices
301  indexvec_vec_index_type current_groupset;
303 
304  // current object index and mapping into contents
305  stringvec_index_type current_object;
307 
308  // current material index and mapping into contents
309  stringvec_index_type current_material;
311 
312  // current materiallib index and mapping into contents
314  indexvec_vec_index_type current_materiallib;
316 
317  // current texmap index and mapping into contents
318  stringvec_index_type current_texmap;
320 
321  // current texmaplib index and mapping into contents
323  indexvec_vec_index_type current_texmaplib;
325 
326  // current shadow_obj index and mapping into contents
327  stringvec_index_type current_shadow_obj;
329 
330  // current trace_obj index and mapping into contents
331  stringvec_index_type current_trace_obj;
333 
337 }; /* basic_parser_state */
338 
339 
340 /**
341  * Composition object for dealing with lex/lacc reentrant interface.
342  *
343  * Lifetime is only until the parse completion of a single file and
344  * its includes.
345  */
346 template<typename PrecisionT,
347  typename charT=char,
348  typename traits=std::char_traits<char>,
349  typename Allocator=std::allocator<char> >
351  typedef charT char_type;
352  typedef traits traits_type;
353  typedef Allocator allocator;
354 
358 
360 
361  parser_state_type parser_state;
362 
363  parser_type parser;
364  basic_parser_type *basic_parser;
366 
367  basic_parser_extra(basic_parser_type *p, contents_type *c);
368 };
369 
370 
371 template<typename PrecisionT,
372  typename charT,
373  typename traits,
374  typename Allocator>
375 void set_working_groupset(basic_parser_extra<PrecisionT, charT, traits,
376  Allocator> &extra)
377 {
379  extra_type;
380 
381  typedef typename extra_type::contents_type contents_type;
382  typedef typename extra_type::parser_state_type parser_state_type;
383 
384  typename parser_state_type::groupset_index_map_type::const_iterator res =
386  find(extra.parser_state.working_stringset);
387 
388  if (res != extra.parser_state.groupset_index_map.end()) {
389  extra.parser_state.current_groupset = res->second;
390  } else {
391  typename parser_state_type::indexvec_type new_grpset;
392  new_grpset.reserve(extra.parser_state.working_stringset.size());
393 
394  // not already seen, set in groupset_index_map
395  typename parser_state_type::stringset_type::const_iterator key =
396  extra.parser_state.working_stringset.begin();
397 
398  while (key != extra.parser_state.working_stringset.end()) {
399  typename parser_state_type::string_index_map_type::const_iterator
400  prev = extra.parser_state.group_index_map.find(*key);
401 
402  if (prev != extra.parser_state.group_index_map.end()) {
403  new_grpset.push_back(prev->second);
404  } else {
405  // never seen this group name before, add to contents and maps
406  new_grpset.push_back(extra.contents->group_set.size());
407 
408  extra.contents->group_set.push_back(*key);
409 
410  extra.contents->groupchar_set.push_back(bu_strdup(key->c_str()));
411 
412  extra.parser_state.group_index_map[*key] = new_grpset.back();
413  }
414  ++key;
415  }
416 
417  // sort the new index set to ensure unique for all ordering
418  std::sort(new_grpset.begin(), new_grpset.end());
419 
420  // map this set of groupname strings to the location in contents for
421  // fast lookup later if needed
422  extra.parser_state.
423  groupset_index_map[extra.parser_state.working_stringset] =
424  extra.contents->groupindex_set.size();
425 
426  // set the current working groupset
427  extra.parser_state.current_groupset =
428  extra.contents->groupindex_set.size();
429 
430  // new_grpset now contains a unique set of indices into
431  // contents->group_set;
432  extra.contents->groupindex_set.push_back(new_grpset);
433  }
434 
435  extra.parser_state.working_stringset.clear();
436 
437  extra.parser_state.working_polyattributes.groupset_index =
438  extra.parser_state.current_groupset;
439 
440  extra.parser_state.polyattributes_dirty = true;
441 } /* set working groupset */
442 
443 
444 template<typename PrecisionT,
445  typename charT,
446  typename traits,
447  typename Allocator>
448 void set_working_object(basic_parser_extra<PrecisionT, charT, traits,
449  Allocator> &extra)
450 {
452  typedef typename extra_type::contents_type contents_type;
453  typedef typename extra_type::parser_state_type parser_state_type;
454  typedef typename contents_type::string_type string_type;
455 
456  typename parser_state_type::object_index_map_type::iterator res =
458  find(extra.parser_state.working_string);
459 
460  if (res != extra.parser_state.object_index_map.end()) {
461  extra.parser_state.current_object = res->second;
462  extra.parser_state.working_string.clear();
463  } else {
464  extra.parser_state.current_object = extra.contents->object_set.size();
465 
466  string_type &working_string = extra.parser_state.working_string;
467 
468  extra.contents->object_set.push_back(working_string);
469 
470  char *objectString = bu_strdup(working_string.c_str());
471 
472  extra.contents->objectchar_set.push_back(objectString);
473  }
474 
475  extra.parser_state.working_polyattributes.object_index =
476  extra.parser_state.current_object;
477 
478  extra.parser_state.polyattributes_dirty = true;
479 } /* set_working_object */
480 
481 
482 template<typename PrecisionT,
483  typename charT,
484  typename traits,
485  typename Allocator>
486 void set_working_material(basic_parser_extra<PrecisionT, charT, traits,
487  Allocator> &extra)
488 {
490  typedef typename extra_type::contents_type contents_type;
491  typedef typename extra_type::parser_state_type parser_state_type;
492  typedef typename contents_type::string_type string_type;
493 
494  typename parser_state_type::material_index_map_type::iterator res =
496  find(extra.parser_state.working_string);
497 
498  if (res != extra.parser_state.material_index_map.end()) {
499  extra.parser_state.current_material = res->second;
500  extra.parser_state.working_string.clear();
501  } else {
502  extra.parser_state.current_material =
503  extra.contents->material_set.size();
504 
505  string_type &working_string = extra.parser_state.working_string;
506 
507  extra.contents->material_set.push_back(working_string);
508 
509  char *materialString = bu_strdup(working_string.c_str());
510 
511  extra.contents->materialchar_set.push_back(materialString);
512  }
513 
514  extra.parser_state.working_polyattributes.material_index =
515  extra.parser_state.current_material;
516 
517  extra.parser_state.polyattributes_dirty = true;
518 } /* set_working_material */
519 
520 template<typename PrecisionT,
521  typename charT,
522  typename traits,
523  typename Allocator>
524 void set_working_materiallib(basic_parser_extra<PrecisionT, charT, traits,
525  Allocator> &extra)
526 {
528  typedef typename extra_type::contents_type contents_type;
529  typedef typename extra_type::parser_state_type parser_state_type;
530  typedef typename contents_type::string_type string_type;
531  typedef typename contents_type::stringvec_type stringvec_type;
532 
533  typename parser_state_type::materiallibset_index_map_type::const_iterator
535  find(extra.parser_state.working_stringset);
536 
537  if (res != extra.parser_state.materiallibset_index_map.end()) {
538  extra.parser_state.current_materiallib = res->second;
539  extra.parser_state.working_stringset.clear();
540  } else {
541  typename parser_state_type::indexvec_type new_mtllibset;
542  new_mtllibset.reserve(extra.parser_state.working_stringset.size());
543 
544  // not already seen, set in materiallibset_index_map
545  typename parser_state_type::stringset_type::const_iterator key =
546  extra.parser_state.working_stringset.begin();
547 
548  while (key != extra.parser_state.working_stringset.end()) {
549  typename parser_state_type::string_index_map_type::const_iterator
550  prev = extra.parser_state.materiallib_index_map.find(*key);
551 
552  if (prev != extra.parser_state.materiallib_index_map.end()) {
553  new_mtllibset.push_back(prev->second);
554  } else {
555  // never seen this materiallib name before, add to contents and
556  // maps
557  stringvec_type &matlib_set = extra.contents->materiallib_set;
558 
559  new_mtllibset.push_back(matlib_set.size());
560 
561  matlib_set.push_back(*key);
562 
563  string_type &matlib_name = matlib_set.back();
564 
565  char *matlibString = bu_strdup(matlib_name.c_str());
566 
567  extra.contents->materiallibchar_set.push_back(matlibString);
568 
569  extra.parser_state.materiallib_index_map[*key] =
570  new_mtllibset.back();
571  }
572  ++key;
573  }
574 
575  // sort the new index set to ensure unique for all ordering
576  std::sort(new_mtllibset.begin(), new_mtllibset.end());
577 
578  // map this set of mtllibname strings to the location in contents for
579  // fast lookup later if needed
580  extra.parser_state.
581  materiallibset_index_map[extra.parser_state.working_stringset] =
582  extra.contents->materiallibindex_set.size();
583 
584  // set the current working mtllibset
585  extra.parser_state.current_materiallib =
586  extra.contents->materiallibindex_set.size();
587 
588  // new_mtllibset now contains a unique set of indices into
589  // contents->materiallib_set;
590  extra.contents->materiallibindex_set.
591  resize(extra.contents->materiallibindex_set.size() + 1);
592 
593  swap(extra.contents->materiallibindex_set.back(), new_mtllibset);
594  }
595 
596  extra.parser_state.working_stringset.clear();
597 
598  extra.parser_state.working_polyattributes.materiallibset_index =
599  extra.parser_state.current_materiallib;
600 
601  extra.parser_state.polyattributes_dirty = true;
602 } /* set_working_materiallib */
603 
604 
605 template<typename PrecisionT,
606  typename charT,
607  typename traits,
608  typename Allocator>
609 void set_working_texmap(basic_parser_extra<PrecisionT, charT, traits,
610  Allocator> &extra)
611 {
613  typedef typename extra_type::contents_type contents_type;
614  typedef typename extra_type::parser_state_type parser_state_type;
615  typedef typename contents_type::string_type string_type;
616 
617  typename parser_state_type::texmap_index_map_type::iterator res =
619  find(extra.parser_state.working_string);
620 
621  if (res != extra.parser_state.texmap_index_map.end()) {
622  extra.parser_state.current_texmap = res->second;
623  extra.parser_state.working_string.clear();
624  } else {
625  extra.parser_state.current_texmap = extra.contents->texmap_set.size();
626 
627  string_type &working_string = extra.parser_state.working_string;
628 
629  extra.contents->texmap_set.push_back(working_string);
630 
631  char *texmapString = bu_strdup(working_string.c_str());
632 
633  extra.contents->texmapchar_set.push_back(texmapString);
634  }
635 
636  extra.parser_state.working_polyattributes.texmap_index =
637  extra.parser_state.current_texmap;
638 
639  extra.parser_state.polyattributes_dirty = true;
640 } /* set_working_texmap */
641 
642 
643 template<typename PrecisionT,
644  typename charT,
645  typename traits,
646  typename Allocator>
647 void set_working_texmaplib(basic_parser_extra<PrecisionT, charT, traits,
648  Allocator> &extra)
649 {
651  typedef typename extra_type::contents_type contents_type;
652  typedef typename extra_type::parser_state_type parser_state_type;
653  typedef typename contents_type::stringvec_type stringvec_type;
654 
655  typename parser_state_type::texmaplibset_index_map_type::const_iterator res
657  find(extra.parser_state.working_stringset);
658 
659  if (res != extra.parser_state.texmaplibset_index_map.end()) {
660  extra.parser_state.current_texmaplib = res->second;
661  extra.parser_state.working_stringset.clear();
662  } else {
663  typename parser_state_type::indexvec_type new_texlibset;
664  new_texlibset.reserve(extra.parser_state.working_stringset.size());
665 
666  // not already seen, set in texmaplibset_index_map
667  typename parser_state_type::stringset_type::const_iterator key =
668  extra.parser_state.working_stringset.begin();
669 
670  while (key != extra.parser_state.working_stringset.end()) {
671  typename parser_state_type::string_index_map_type::const_iterator
672  prev = extra.parser_state.texmaplib_index_map.find(*key);
673 
674  if (prev != extra.parser_state.texmaplib_index_map.end()) {
675  new_texlibset.push_back(prev->second);
676  } else {
677  stringvec_type &texmaplib_set = extra.contents->texmaplib_set;
678 
679  // never seen this texmaplib name before, add to contents and
680  // maps
681  new_texlibset.push_back(texmaplib_set.size());
682 
683  texmaplib_set.push_back(*key);
684 
685  char *texmapString = bu_strdup(key->c_str());
686 
687  extra.contents->texmaplibchar_set.push_back(texmapString);
688 
689  extra.parser_state.texmaplib_index_map[*key] =
690  new_texlibset.back();
691  }
692  ++key;
693  }
694 
695  // sort the new index set to ensure unique for all ordering
696  std::sort(new_texlibset.begin(), new_texlibset.end());
697 
698  // map this set of mtllibname strings to the location in contents for
699  // fast lookup later if needed
700  extra.parser_state.
701  texmaplibset_index_map[extra.parser_state.working_stringset] =
702  extra.contents->texmaplibindex_set.size();
703 
704  // set the current working texmaplibset
705  extra.parser_state.current_texmaplib =
706  extra.contents->texmaplibindex_set.size();
707 
708  // new_texlibset now contains a unique set of indices into
709  // contents->texmaplib_set;
710  extra.contents->texmaplibindex_set.
711  resize(extra.contents->texmaplibindex_set.size() + 1);
712 
713  swap(extra.contents->texmaplibindex_set.back(), new_texlibset);
714  }
715 
716  extra.parser_state.working_stringset.clear();
717 
718  extra.parser_state.working_polyattributes.texmaplibset_index =
719  extra.parser_state.current_texmaplib;
720 
721  extra.parser_state.polyattributes_dirty = true;
722 } /* set_working_texmaplib */
723 
724 
725 template<typename PrecisionT,
726  typename charT,
727  typename traits,
728  typename Allocator>
729 void set_working_shadow_obj(basic_parser_extra<PrecisionT, charT, traits,
730  Allocator> &extra)
731 {
733  typedef typename extra_type::contents_type contents_type;
734  typedef typename extra_type::parser_state_type parser_state_type;
735  typedef typename contents_type::string_type string_type;
736 
737  typename parser_state_type::shadow_obj_index_map_type::iterator res =
739  find(extra.parser_state.working_string);
740 
741  if (res != extra.parser_state.shadow_obj_index_map.end()) {
742  extra.parser_state.current_shadow_obj = res->second;
743  extra.parser_state.working_string.clear();
744  } else {
745  extra.parser_state.current_shadow_obj =
746  extra.contents->shadow_obj_set.size();
747 
748  string_type &working_string = extra.parser_state.working_string;
749 
750  extra.contents->shadow_obj_set.push_back(working_string);
751 
752  char *shadowObjString = bu_strdup(working_string.c_str());
753 
754  extra.contents->shadow_objchar_set.push_back(shadowObjString);
755  }
756 
757  extra.parser_state.working_polyattributes.shadow_obj_index =
758  extra.parser_state.current_shadow_obj;
759 
760  extra.parser_state.polyattributes_dirty = true;
761 } /* set_working_shadow_obj */
762 
763 
764 template<typename PrecisionT,
765  typename charT,
766  typename traits,
767  typename Allocator>
768 void set_working_trace_obj(basic_parser_extra<PrecisionT, charT, traits,
769  Allocator> &extra)
770 {
772  typedef typename extra_type::contents_type contents_type;
773  typedef typename extra_type::parser_state_type parser_state_type;
774  typedef typename contents_type::string_type string_type;
775 
776  typename parser_state_type::trace_obj_index_map_type::iterator res =
778  find(extra.parser_state.working_string);
779 
780  if (res != extra.parser_state.trace_obj_index_map.end()) {
781  extra.parser_state.current_trace_obj = res->second;
782  extra.parser_state.working_string.clear();
783  } else {
784  extra.parser_state.current_trace_obj =
785  extra.contents->trace_obj_set.size();
786 
787  string_type &working_string = extra.parser_state.working_string;
788 
789  extra.contents->trace_obj_set.push_back(working_string);
790 
791  char *traceObjString = bu_strdup(working_string.c_str());
792 
793  extra.contents->trace_objchar_set.push_back(traceObjString);
794  }
795 
796  extra.parser_state.working_polyattributes.trace_obj_index =
797  extra.parser_state.current_trace_obj;
798 
799  extra.parser_state.polyattributes_dirty = true;
800 } /* set_working_trace_obj */
801 
802 
803 template<typename PrecisionT,
804  typename charT,
805  typename traits,
806  typename Allocator>
807 void set_working_polygattributes(basic_parser_extra<PrecisionT, charT, traits,
808  Allocator> &extra)
809 {
811  typedef typename extra_type::contents_type contents_type;
812  typedef typename extra_type::parser_state_type parser_state_type;
813 
814  typename parser_state_type::polyattributes_index_map_type::iterator res =
816  find(extra.parser_state.working_polyattributes);
817 
818  if (res != extra.parser_state.polyattributes_index_map.end()) {
819  extra.parser_state.current_polyattributes = res->second;
820  } else {
821  extra.parser_state.current_polyattributes =
822  extra.contents->polyattributes_set.size();
823 
824  extra.contents->polyattributes_set.
825  resize(extra.contents->polyattributes_set.size() + 1,
826  extra.parser_state.working_polyattributes);
827  }
828 }
829 
830 
831 /**
832  * Set the initial values of the lookup tables to the first element in the
833  * contents
834  */
835 template<typename PrecisionT,
836  typename charT,
837  typename traits,
838  typename Allocator>
841 : parser(NULL)
842 , basic_parser(p)
843 , contents(c)
844 {
845  parser_state.working_stringset.insert("default");
846  // since the working string is empty, these will set to the default ""
847  set_working_groupset(*this);
848  set_working_object(*this);
849  set_working_material(*this);
850  parser_state.working_stringset.insert("");
852  set_working_texmap(*this);
853  parser_state.working_stringset.insert("");
854  set_working_texmaplib(*this);
855  set_working_shadow_obj(*this);
856  set_working_trace_obj(*this);
863 }
864 
865 
866 /**
867  * InputIterator is a model of pointer to FileNode concept
868  * OutputStreamT is a model of OutputStream
869  */
870 template<typename InputIterator, typename OutputStreamT>
871 void include_chain_formatter(InputIterator first, InputIterator last,
872  OutputStreamT &str)
873 {
874  if (first == last) {
875  return;
876  }
877 
878  str << "In file included from " << first->path;
879 
880  while (++first != last) {
881  str << "\n from " << first->path;
882  }
883 
884  str << "\n";
885 }
886 
887 
888 template<typename ParserStateT>
889 void verbose_output_formatter(ParserStateT &state, const char *s)
890 {
891  if (state.file_stack.size() > 1) {
892  include_chain_formatter(state.file_stack.begin(),
893  state.file_stack.end(), state.err);
894  }
895 
896  state.err << state.file_stack.back().path << ":"
897  << state.file_stack.back().lineno << ": " << s;
898 }
899 
900 
901 template<typename ParserStateT>
902 inline void output_formatter(ParserStateT &state, const char *s)
903 {
904  state.err << state.file_stack.back().path << ":"
905  << state.file_stack.back().lineno << ": " << s;
906 }
907 
911 
912 } /* namespace obj */
913 } /* namespace gcv */
914 } /* namespace cad */
915 
916 
917 #endif
918 
919 /*
920  * Local Variables:
921  * mode: C++
922  * tab-width: 8
923  * indent-tabs-mode: t
924  * c-file-style: "stroustrup"
925  * End:
926  * ex: shiftwidth=4 tabstop=8
927  */
std::basic_stringstream< typename string_type::value_type, typename string_type::traits_type, typename string_type::allocator_type > stringstream_type
void set_working_polygattributes(basic_parser_extra< PrecisionT, charT, traits, Allocator > &extra)
polygonal_nv_indexvec_type pologonal_nv_indexlist
std::map< stringset_type, indexvec_vec_index_type > materiallibset_index_map_type
contents_type::stringvec_type stringvec_type
obj_polygonal_attributes_t working_polyattributes
basic_parser_state< contents_type > parser_state_type
if lu s
Definition: nmg_mod.c:3860
void set_working_shadow_obj(basic_parser_extra< PrecisionT, charT, traits, Allocator > &extra)
#define N
Definition: randmt.c:39
basic_parser_extra< float, char > objCombinedState
tuple< size_t, 2 > polygonal_nv_index_type
std::vector< file_node > file_stack
stringvec_index_type current_shadow_obj
shadow_obj_index_map_type shadow_obj_index_map
std::vector< size_t > indexvec_type
polygonal_tv_indexvec_type pologonal_tv_indexlist
texmap_index_map_type texmap_index_map
std::vector< polygonal_nv_index_type > polygonal_nv_indexvec_type
tuple< index_type, 1 > index1_type
tuple< size_t, 2 > polygonal_tv_index_type
Header file for the BRL-CAD common definitions.
contents_type::polygonal_nv_indexvec_type polygonal_nv_indexvec_type
std::map< obj_polygonal_attributes_t, polyattributes_vec_index_type > polyattributes_index_map_type
polyattributes_vec_type polyattributes_set
string_index_map_type materiallib_index_map
std::set< string_type > stringset_type
indexvec_vec_index_type current_materiallib
std::map< stringset_type, indexvec_vec_index_type > texmaplibset_index_map_type
indexvec_vec_type::size_type indexvec_vec_index_type
polyattributes_index_map_type polyattributes_index_map
polygonal_v_indexvec_type line_v_indexlist
void set_working_groupset(basic_parser_extra< PrecisionT, charT, traits, Allocator > &extra)
std::map< string_type, stringvec_index_type > trace_obj_index_map_type
indexvec_vec_index_type current_groupset
void output_formatter(ParserStateT &state, const char *s)
std::vector< polygonal_tnv_index_type > polygonal_tnv_indexvec_type
void set_working_object(basic_parser_extra< PrecisionT, charT, traits, Allocator > &extra)
polygonal_v_indexvec_type pologonal_v_indexlist
trace_obj_index_map_type trace_obj_index_map
void compare(tuple< T, N > &lhs, const tuple< T, N > &rhs)
void set_working_material(basic_parser_extra< PrecisionT, charT, traits, Allocator > &extra)
contents_type::charvec_type charvec_type
std::map< string_type, stringvec_index_type > shadow_obj_index_map_type
contents_type::polygonal_v_indexvec_type polygonal_v_indexvec_type
basic_obj_parser< charT, traits, Allocator > basic_parser_type
std::pair< size_t, size_t > indexloc_t
object_index_map_type object_index_map
std::vector< obj_polygonal_attributes_t > polyattributes_vec_type
contents_type::polyattributes_vec_type polyattributes_vec_type
std::vector< gvertex_t > gvertices_list
tuple< precision_type, 3 > tvertex_t
void include_chain_formatter(InputIterator first, InputIterator last, OutputStreamT &str)
bool operator<(const obj_polygonal_attributes_t &lhs, const obj_polygonal_attributes_t &rhs)
tuple< precision_type, 4 > gvertex_t
std::vector< polygonal_v_index_type > polygonal_v_indexvec_type
basic_parser_extra(basic_parser_type *p, contents_type *c)
std::basic_string< charT, traits, Allocator > string_type
bool operator==(const tuple< T, N > &lhs, const tuple< T, N > &rhs)
groupset_index_map_type groupset_index_map
std::map< string_type, stringvec_index_type > texmap_index_map_type
tuple< precision_type, 3 > nvertex_t
void set_working_texmap(basic_parser_extra< PrecisionT, charT, traits, Allocator > &extra)
bool compare(tuple< T, N > &lhs, const tuple< T, N > &rhs)
string_index_map_type group_index_map
std::map< stringset_type, indexvec_vec_index_type > groupset_index_map_type
void set_working_materiallib(basic_parser_extra< PrecisionT, charT, traits, Allocator > &extra)
std::map< string_type, stringvec_index_type > object_index_map_type
stringvec_index_type current_trace_obj
std::vector< indexloc_t > indexloc_vec_type
polygonal_tv_indexvec_type line_tv_indexlist
string_index_map_type texmaplib_index_map
std::vector< indexvec_type > indexvec_vec_type
void set_working_trace_obj(basic_parser_extra< PrecisionT, charT, traits, Allocator > &extra)
std::vector< nvertex_t > tvertices_list
polygonal_tnv_indexvec_type pologonal_tnv_indexlist
tuple< index_type, 3 > index3_type
materiallibset_index_map_type materiallibset_index_map
void verbose_output_formatter(ParserStateT &state, const char *s)
tuple< index_type, 2 > index2_type
stringvec_type::size_type stringvec_index_type
polyattributes_vec_type::size_type polyattributes_vec_index_type
basic_obj_parser< char > objParser
contents_type::polygonal_tnv_indexvec_type polygonal_tnv_indexvec_type
std::map< string_type, stringvec_index_type > material_index_map_type
indexvec_vec_index_type current_texmaplib
contents_type::string_type string_type
std::vector< polygonal_tv_index_type > polygonal_tv_indexvec_type
std::vector< string_type > stringvec_type
material_index_map_type material_index_map
contents_type::indexvec_vec_type indexvec_vec_type
std::map< string_type, typename charvec_type::size_type > string_index_map_type
contents_type::polygonal_tv_indexvec_type polygonal_tv_indexvec_type
std::vector< tvertex_t > nvertices_list
polyattributes_vec_index_type current_polyattributes
std::basic_string< charT, traits, Allocator > string_type
void set_working_texmaplib(basic_parser_extra< PrecisionT, charT, traits, Allocator > &extra)
basic_obj_contents< PrecisionT, charT, traits, Allocator > contents_type
std::vector< const charT * > charvec_type
contents_type::indexvec_type indexvec_type
tuple< size_t, 3 > polygonal_tnv_index_type
basic_obj_contents< float, char > objFileContents
stringvec_index_type current_material
#define bu_strdup(s)
Definition: str.h:71
texmaplibset_index_map_type texmaplibset_index_map
polygonal_v_indexvec_type point_v_indexlist