G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsFileData.hpp
Go to the documentation of this file.
1 
15 #pragma once
16 
17 
18 //#include <string>
19 //#include <iostream>
20 //#include <fstream>
21 
22 #include <gsNurbs/gsKnotVector.h>
23 
24 #include <rapidxml/rapidxml.hpp> // External file
25 #include <rapidxml/rapidxml_print.hpp> // External file
26 
27 #ifdef gsOpennurbs_ENABLED
29 #endif
30 
31 #ifdef gsOpenCascade_ENABLED
33 #endif
34 
35 #ifdef GISMO_WITH_PSOLID // Extension files
37 #endif
38 
39 
40 #include <gzstream/gzstream.h>
41 #include <gsIO/gsFileManager.h>
42 
43 namespace gismo {
44 
45 template<class T>
46 gsFileData<T>::gsFileData()
47 {
48  data = new FileData;
49  data->makeRoot();
50 }
51 
52 template<class T>
53 gsFileData<T>::gsFileData(String const & fn, bool recursive)
54 {
55  data = new FileData;
56  data->makeRoot();
57  this->read(fn, recursive);
58 }
59 
60 template<class T>
62 {
63  data->clear();
64  delete data;
65 }
66 
67 
68 template<class T> void
70 {
71  data->clear();
72  data->makeRoot(); // ready to re-use
73 }
74 
75 
76 template<class T>
77 std::ostream & gsFileData<T>::print(std::ostream &os) const
78 {
79  //rapidxml::print_no_indenting
80  os<< *data;
81  return os;
82 }
83 
84 
85 template<class T> void
86 gsFileData<T>::dump(std::string const & fname) const
87 { save(fname); }
88 
89 
90 template<class T> void
91 gsFileData<T>::addComment(std::string const & message)
92 {
93  gsXmlNode * comment = internal::makeComment(message, *data);
94  data->prepend_node(comment);
95 }
96 
97 template<class T> void
98 gsFileData<T>::save(std::string const & fname, bool compress) const
99 {
100  gsXmlNode * comment = internal::makeComment("This file was created by G+Smo "
101  GISMO_VERSION, *data);
102  data->prepend_node(comment);
103 
104  gsXmlNode * declNode = data->allocate_node(rapidxml::node_type::node_declaration);
105  declNode->append_attribute(data->allocate_attribute("version","1.0"));
106  declNode->append_attribute(data->allocate_attribute("encoding","UTF-8"));
107  data->prepend_node(declNode);
108 
109  if (compress)
110  {
111  saveCompressed(fname);
112  return;
113  }
114 
115  String tmp = gsFileManager::getExtension(fname);
116  if (tmp != "xml" )
117  tmp = fname + ".xml";
118  else
119  tmp = fname;
120 
121  m_lastPath = tmp;
122 
123  std::ofstream fn( tmp.c_str() );
124  //rapidxml::print_no_indenting
125  fn<< *data;
126  fn.close();
127  data->remove_node( data->first_node() );
128 }
129 
130 template<class T> void
131 gsFileData<T>::saveCompressed(std::string const & fname) const
132 {
133  String tmp = gsFileManager::getExtension(fname);
134  if (tmp != "gz" )
135  {
136  if (tmp != "xml" )
137  tmp = fname + ".xml.gz";
138  else
139  tmp = fname + ".gz";
140  }
141  else
142  tmp = fname;
143 
144  m_lastPath = tmp;
145 
146  ogzstream fn( tmp.c_str() );
147  fn << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
148  //rapidxml::print_no_indenting
149  fn<< *data;
150  fn.close();
151 }
152 
153 template<class T> void
154 gsFileData<T>::ioError(int lineNumber, const std::string& str)
155 {
156  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
157  <<": IO error near line "<<lineNumber<<std::endl;
158  throw std::runtime_error(str + " failed");
159 }
160 
161 template<class T>
162 bool gsFileData<T>::read(String const & fn, bool recursive)
163 {
164  m_lastPath = gsFileManager::find(fn);
165  if ( m_lastPath.empty() )
166  {
167  gsWarn<<"gsFileData: Problem with file "<<fn<<": File not found.\n";
168  gsWarn<<"search paths: "<< gsFileManager::getSearchPaths()<<"\n";
169  return false;
170  }
171 
172  // Identify filetype by extension
173  String ext = gsFileManager::getExtension(fn);
174 
175  if (ext== "xml")
176  return readXmlFile(m_lastPath, recursive);
177  else if (ext== "gz" && util::ends_with(m_lastPath, ".xml.gz") )
178  return readXmlGzFile(m_lastPath, recursive);
179  else if (ext== "txt")
180  return readGeompFile(m_lastPath);
181  else if (ext== "g2")
182  return readGoToolsFile(m_lastPath);
183  else if (ext== "axl")
184  return readAxelFile(m_lastPath);
185  else if (ext== "off")
186  return readOffFile(m_lastPath);
187 #ifdef gsOpennurbs_ENABLED
188  else if (ext== "3dm")
189  return read3dmFile(m_lastPath);
190 #endif
191 #ifdef gsOpenCascade_ENABLED
192  else if (ext== "brep")
193  return readBrepFile(m_lastPath);
194  //else if (ext== "iges")
195  // return readIgesFile(m_lastPath);
196  //else if (ext== "step")
197  // return readStepFile(m_lastPath);
198 #endif
199 #ifdef GISMO_WITH_PSOLID
200  else if (ext== "xmt_txt")
201  return readParasolidFile(m_lastPath);
202  else if (ext== "x_t")
203  return readParasolidFile(m_lastPath);
204  else if (ext== "xmt_bin")
205  return readParasolidFile(m_lastPath);
206 #endif
207  else if (ext== "obj")
208  return readObjFile(m_lastPath);
209  else if (ext== "stl")
210  return readStlFile(m_lastPath);
211  else if (ext=="igs" || ext== "iges")
212  return readIgesFile(m_lastPath);
213 // else if (ext=="bv")
214 // return readBezierView(m_lastPath);
215  else if (ext=="x3d")
216  return readX3dFile(m_lastPath);
217  else if (ext=="csv")
218  return readCsvFile(m_lastPath);
219  else
220  {
221  gsWarn<<"gsFileData: Problem with file "<<fn<<": Unknown extension \"."<<ext<<"\".\n";
222  return false;
223  }
224 }
225 
226 /*---------- Native Gismo format */
227 
228 template<class T>
229 bool gsFileData<T>::readXmlFile( String const & fn, bool recursive)
230 {
231  // Open file
232  std::ifstream file(fn.c_str(), std::ios::in);
233  if ( file.fail() )
234  {gsWarn<<"gsFileData: Problem with file "<<fn<<": Cannot open file stream.\n"; return false; }
235 
236  return readGismoXmlStream(file, recursive);
237 }
238 
239 template<class T>
240 bool gsFileData<T>::readXmlGzFile( String const & fn, bool recursive)
241 {
242  // Open file
243  igzstream file(fn.c_str(), std::ios::in);
244  if ( file.fail() )
245  {gsWarn<<"gsFileData: Problem with file "<<fn<<": Cannot open file stream.\n"; return false; }
246 
247  return readGismoXmlStream(file, recursive);
248 }
249 
250 
251 template<class T>
252 bool gsFileData<T>::readGismoXmlStream(std::istream & is, bool recursive)
253 {
254  m_buffer.emplace_back();
255  std::vector<char> & buffer = m_buffer.back();
256  buffer.assign( std::istreambuf_iterator<char>(is.rdbuf() ),
257  std::istreambuf_iterator<char>() );
258  buffer.push_back('\0');
259  // Load file contents
260  data->parse<0>(&buffer[0], true);
261 
262  gsXmlNode * ln = data->last_node("xml");
263  if ( !ln )
264  {
265  gsWarn<< "gsFileData: Problem with file "<<m_lastPath
266  <<": Invalid XML file, no root tag <xml> found.\n";
267  assert( ln ) ;
268  }
269 
270  if (recursive)
271  {
272  std::list<std::string> ifn;
273  for (gsXmlNode * child = ln->first_node("xmlfile") ;
274  child; child = child->next_sibling("xmlfile") )
275  {
276  ifn.push_back( child->value() );
277  //ln->remove_node(child);
278  }
279 
280  std::string cfn = gsFileManager::getPath(m_lastPath);
281  for (auto & f : ifn)
282  {
283  readXmlFile(cfn + f);
284  }
285  }
286 
287  gsXmlNode * root = data->getRoot();
288  root->merge_sibling(ln);
289  data->remove_node(ln);
290 
291  // TO DO: Check if it contains unknown tags...
292  return true;
293 }
294 
295 template<class T>
296 void gsFileData<T>::addInclude( const std::string & filename, const real_t & time,
297  const index_t & id, const std::string & label)
298 {
299  GISMO_ASSERT( filename!="", "No filename provided for include!");
300  gsXmlNode* node = internal::makeNode("xmlfile", filename, *data);
301  if (-1. != time)
302  node->append_attribute(internal::makeAttribute("time", std::to_string( cast<real_t,double >( time ) ), *data));
303  data->appendToRoot(node,id, label);
304 }
305 
306 
307 template<class T>
308 void gsFileData<T>::getInclude(gsFileData<T> & res, index_t id, real_t time, std::string label)
309 {
310  // Ensures that only one argument is actually provided
311  GISMO_ENSURE(( (id!=-1) ^ (time!=-1.) ^ (label!="") ) &&
312  !(id!=-1 && time!=-1. && label!=""),
313  "gsFileData::getInclude("<<id<<","<<time<<","<<label<<"), too many arguments provided!");
314  std::string attr_name, attr_string;
315 
316  // Attribute name and string representation, depending on pprovided input.
317  if ( id!=-1 )
318  {
319  attr_name = "id";
320  attr_string = std::to_string(id);
321  }
322  else if ( time!=-1)
323  {
324  attr_name = "time";
325  attr_string = cast<real_t,double>( time );
326  }
327  else if ( label!="")
328  {
329  attr_name = "label";
330  attr_string = label;
331  }
332 
333  gsXmlNode * root = getXmlRoot();
334 
335  gsXmlNode * nd = internal::searchNode(root, attr_name, attr_string, "xmlfile");
336  if (nd)
337  {
338  std::string filename = gsFileManager::getPath(m_lastPath) + nd->value();
339  res.clear();
340  res.read(filename);
341  return;
342  }
343  GISMO_ERROR("Include with " << attr_name << "=" << attr_string << " does not exist!");
344 }
345 
346 /*---------- Axl file */
347 
348 template<class T>
349 bool gsFileData<T>::readAxelFile( String const & fn )
350 {
351  // Open file
352  std::ifstream file(fn.c_str(), std::ios::in);
353  if ( file.fail() )
354  {gsWarn<<"gsFileData: Problem with file "<<fn<<": Cannot open file stream.\n"; return false; }
355 
356  std::vector<char> buffer(
357  std::istreambuf_iterator<char>(file.rdbuf() ),
358  std::istreambuf_iterator<char>() );
359  buffer.push_back('\0');
360 
361  // Read Axel Xml data
362  FileData axldata;
363  axldata.parse<0>(&buffer[0]);
364 
365  // Look for the root <axl>
366  gsXmlNode * node = axldata.first_node("axl");
367  String s;
368 
369  // Translate to Gismo XML
370  for (gsXmlNode * child = node->first_node(); child; child = child->next_sibling())
371  {
372  s = child->name();
373  if ( s == "curve" )
374  { readAxelCurve(child); }
375  if ( s == "surface" )
376  { readAxelSurface(child); }
377  if ( s == "mesh" )
378  { readAxelMesh(child); }
379  }
380 
381  buffer.clear();
382  axldata.clear();
383  return true;
384 };
385 
386 template<class T>
387 bool gsFileData<T>::readAxelCurve(gsXmlNode * node )
388 {
389  std::stringstream str;
390 
391  //bool rational(true);
392 
393  gsXmlNode* g = internal::makeNode("Geometry", *data);
394  g->append_attribute( internal::makeAttribute("type", "BSpline", *data) );
395  data->appendToRoot(g);
396  gsXmlNode * parent= g;
397 
398  gsXmlNode* tmp = node->first_node("dimension");
399  String geoDim = tmp->value();
400 
401  gsXmlNode* b = internal::makeNode("Basis", *data);
402  b->append_attribute( internal::makeAttribute("type", "BSplineBasis", *data) );
403  parent->append_node(b);
404 
405  unsigned d;
406  tmp= node->first_node("order");
407  str.str( tmp->value() );
408  str >> d; d-=1;
409 
410  tmp = node->first_node("knots");
411  g = internal::makeNode("KnotVector", tmp->value(), *data);
412  g->append_attribute( internal::makeAttribute("degree", d, *data ) );
413  b->append_node(g);
414 
415  // Coefficients
416  tmp = node->first_node("points");
417  g = internal::makeNode("coefs", tmp->value(), *data);
418  g->append_attribute( internal::makeAttribute("geoDim", geoDim, *data ) );
419  parent->append_node(g);
420 
421  return true;
422 };
423 
424 template<class T>
425 bool gsFileData<T>::readAxelSurface(gsXmlNode * node )
426 {
427  std::stringstream str;
428 
429  gsXmlNode* g = internal::makeNode("Geometry", *data);
430  g->append_attribute( internal::makeAttribute("type", "TensorBSpline2", *data) );
431  data->appendToRoot(g);
432  gsXmlNode * parent = g;
433 
434  //gsXmlNode* tmp = node->first_node("dimension");// dimension is 3
435 
436  unsigned d[2];
437  gsXmlNode * tmp = node->first_node("order");
438  str.clear();
439  str.str( tmp->value() );
440  str >> d[0] >> d[1];
441  d[0]-=1; d[1]-=1;
442 
443  // Tensor Basis
444  gsXmlNode* tb = internal::makeNode("Basis", *data);
445  tb->append_attribute( internal::makeAttribute("type", "TensorBSplineBasis2", *data) );
446  //tb->append_attribute( internal::makeAttribute("parDim", "2", *data ) );
447  parent->append_node(tb);
448 
449  gsXmlNode* b = internal::makeNode("Basis", *data);
450  b->append_attribute( internal::makeAttribute("type", "BSplineBasis", *data) );
451  b->append_attribute( internal::makeAttribute("index", "0", *data) );
452  tb->append_node(b);
453  tmp = node->first_node("knots");
454  g = internal::makeNode("KnotVector", tmp->value(), *data);
455  g->append_attribute( internal::makeAttribute("degree", d[0], *data ) ) ;
456  b->append_node(g);
457 
458  b = internal::makeNode("Basis", *data);
459  b->append_attribute( internal::makeAttribute("type", "BSplineBasis", *data) );
460  b->append_attribute( internal::makeAttribute("index", "1", *data) );
461  tb->append_node(b);
462  tmp = tmp->next_sibling("knots");
463  g = internal::makeNode("KnotVector", tmp->value(), *data);
464  g->append_attribute( internal::makeAttribute("degree", d[1], *data ) ) ;
465  b->append_node(g);
466 
467  // Coefficients
468  tmp = node->first_node("points");
469  g = internal::makeNode("coefs", tmp->value(), *data);
470  g->append_attribute( internal::makeAttribute("geoDim", "3", *data ) );
471  parent->append_node(g);
472 
473  return true;
474 };
475 
476 template<class T>
477 bool gsFileData<T>::readAxelMesh(gsXmlNode * node )
478 {
479  std::ostringstream str;
480  gsXmlNode * tmp = node->first_node("points");
481  GISMO_ASSERT(tmp,"No points in mesh.");
482  str<< tmp->value();
483  tmp = node->first_node("faces");
484  if (tmp)
485  str<< tmp->value();
486  internal::gsXmlNode* g = internal::makeNode("Mesh", str.str(), *data);
487  g->append_attribute(internal::makeAttribute("type", "off", *data ) );
488 
489  tmp = node->first_node("count");
490  GISMO_ASSERT(tmp,"No point count in mesh.");
491  std::istringstream iss(tmp->value());
492  int n;
493  iss >> n;
494  g->append_attribute(internal::makeAttribute("vertices", n, *data ) );
495  iss >> n; iss >> n; //skips one deliberately
496  g->append_attribute( internal::makeAttribute("faces", n, *data ) );
497  internal::gsXmlNode* parent = data->first_node("xml") ;
498  parent->append_node(g);
499 
500  tmp = node->first_node("edges");
501  if (tmp)
502  gsWarn <<"Skipping edges in axl file.\n";
503  return true;
504 }
505 
506 // ******************************** //
507 // GoTools g2 file
508 // ******************************** //
509 
510 template<class T>
511 bool gsFileData<T>::readGoToolsFile( String const & fn )
512 {
513  //Input file
514  std::ifstream file(fn.c_str(),std::ios::in);
515  if ( !file.good() )
516  {gsWarn<<"gsFileData: Problem with file "<<fn<<": Cannot open file stream.\n"; return false; }
517 
518  std::istringstream lnstream;
519  lnstream.unsetf(std::ios_base::skipws);
520 
521  String line;
522 
523  // Node for a Geometry object
524  gsXmlNode * g;
525  // Node for a basis object
526  gsXmlNode * src;
527 
528  // Temporaries
529  bool rational;
530  int ncp, deg, c, parDim(0), geoDim;
531 
532  // Structure:
533  // type, version
534  // geoDim, rational
535  // n_coefs_u order_u
536  // knots_u
537  // n_coefs_v order_v
538  // knots_v
539  // n_coefs_w order_w
540  // knots_w
541  // coefficients
542 
543  while (!file.eof() && getline(file, line))
544  {
545  while (!file.eof() && line == "") getline(file, line);
546 
547  // Read entity type and version line
548  lnstream.clear();
549  lnstream.str(line);
550  if ( !(lnstream >> std::ws >> ncp ) ) continue;
551  if ( !(lnstream >> std::ws >> c ) || c > 1 ) continue;
552  if ( !(lnstream >> std::ws >> c ) || c >9 ) continue;
553  if ( !(lnstream >> std::ws >> c ) || c >9 ) continue;
554 
555  switch (ncp)
556  {
557  case 100: // Class_SplineCurve
558  parDim = 1;
559  break;
560  case 200: // Class_SplineSurface
561  parDim = 2;
562  break;
563  case 700: // Class_SplineVolume
564  parDim = 3;
565  break;
566  case 210: // Class_BoundedSurface
567  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
568  <<": Reading GoTools trimmed surface (ClassType="<<ncp<<") not implemented.\n";
569  break;
570  case 110: // Class_CurveOnSurface
571  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
572  <<": Reading GoTools CurveOnSurface (ClassType="<<ncp<<") not implemented.\n";
573  continue;
574  break;
575  case 120: // Class_Line
576  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
577  <<": Reading GoTools Line (ClassType="<<ncp<<") not implemented.\n";
578  continue;
579  break;
580  case 130: // Class_Circle
581  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
582  <<": Reading GoTools Circle (ClassType="<<ncp<<") not implemented.\n";
583  continue;
584  break;
585  case 140: // Class_Ellipse
586  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
587  <<": Reading GoTools Ellipse (ClassType="<<ncp<<") not implemented.\n";
588  continue;
589  break;
590  case 150: // Class_BoundedCurve
591  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
592  <<": Reading GoTools BoundedCurve (ClassType="<<ncp<<") not implemented.\n";
593  continue;
594  break;
595  case 160: // Class_Hyperbola
596  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
597  <<": Reading GoTools Hyperbola (ClassType="<<ncp<<") not implemented.\n";
598  continue;
599  break;
600  case 170: // Class_Parabola
601  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
602  <<": Reading GoTools Parabola (ClassType="<<ncp<<") not implemented.\n";
603  continue;
604  break;
605  case 211: // Class_SurfaceOnVolume
606  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
607  <<": Reading GoTools SurfaceOnVolume (ClassType="<<ncp<<") not implemented.\n";
608  continue;
609  break;
610  case 220: // Class_GoBaryPolSurface
611  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
612  <<": Reading GoTools GoBaryPolSurface (ClassType="<<ncp<<") not implemented.\n";
613  continue;
614  break;
615  case 230: // Class_GoHBSplineParamSurface
616  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
617  <<": Reading GoTools GoHBSplineParamSurface (ClassType="<<ncp<<") not implemented.\n";
618  continue;
619  break;
620  case 240: // Class_CompositeSurface
621  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
622  <<": Reading GoTools CompositeSurface (ClassType="<<ncp<<") not implemented.\n";
623  continue;
624  break;
625  case 250: // Class_Plane
626  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
627  <<": Reading GoTools Plane (ClassType="<<ncp<<") not implemented.\n";
628  continue;
629  break;
630  case 260: // Class_Cylinder
631  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
632  <<": Reading GoTools Cylinder (ClassType="<<ncp<<") not implemented.\n";
633  continue;
634  break;
635  case 270: // Class_Sphere
636  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
637  <<": Reading GoTools Sphere (ClassType="<<ncp<<") not implemented.\n";
638  continue;
639  break;
640  case 280: // Class_Sphere
641  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
642  <<": Reading GoTools Sphere (ClassType="<<ncp<<") not implemented.\n";
643  continue;
644  break;
645  case 290: // Class_Torus
646  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
647  <<": Reading GoTools Torus (ClassType="<<ncp<<") not implemented.\n";
648  continue;
649  break;
650  case 291: // Class_SurfaceOfRevolution
651  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
652  <<": Reading GoTools SurfaceOfRevolution (ClassType="<<ncp<<") not implemented.\n";
653  continue;
654  break;
655  case 292: // Class_Disc
656  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
657  <<": Reading GoTools Disc (ClassType="<<ncp<<") not implemented.\n";
658  continue;
659  break;
660  case 293: // Class_LRSplineSurface
661  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
662  <<": Reading GoTools LRSplineSurface (ClassType="<<ncp<<") not implemented.\n";
663  continue;
664  break;
665  case 294: // Class_TSplineSurface
666  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
667  <<": Reading GoTools TSplineSurface (ClassType="<<ncp<<") not implemented.\n";
668  continue;
669  break;
670  case 300: // Class_Go3dsObject
671  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
672  <<": Reading GoTools Go3dsObject (ClassType="<<ncp<<") not implemented.\n";
673  continue;
674  break;
675  case 310: // Class_GoHeTriang
676  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
677  <<": Reading GoTools GoHeTriang (ClassType="<<ncp<<") not implemented.\n";
678  continue;
679  break;
680  case 320: // Class_GoSdTriang
681  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
682  <<": Reading GoTools GoSdTriang (ClassType="<<ncp<<") not implemented.\n";
683  continue;
684  break;
685  case 330: // Class_GoQuadMesh
686  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
687  <<": Reading GoTools GoQuadMesh (ClassType="<<ncp<<") not implemented.\n";
688  continue;
689  break;
690  case 340: // Class_GoHybridMesh
691  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
692  <<": Reading GoTools GoHybridMesh (ClassType="<<ncp<<") not implemented.\n";
693  continue;
694  break;
695  case 350: // Class_ParamTriang
696  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
697  <<": Reading GoTools GoHybridMesh (ClassType="<<ncp<<") not implemented.\n";
698  continue;
699  break;
700  case 360: // Class_GoVrmlGeometry
701  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
702  <<": Reading GoTools GoVrmlGeometry (ClassType="<<ncp<<") not implemented.\n";
703  continue;
704  break;
705  case 400: // Class_PointCloud
706  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
707  <<": Reading GoTools PointCloud (ClassType="<<ncp<<") not implemented.\n";
708  continue;
709  break;
710  case 410: // Class_LineCloud
711  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
712  <<": Reading GoTools LineCloud (ClassType="<<ncp<<") not implemented.\n";
713  continue;
714  break;
715  case 500: // Class_GoTriangleSets
716  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
717  <<": Reading GoTools GoTriangleSets (ClassType="<<ncp<<") not implemented.\n";
718  continue;
719  break;
720  case 510: // Class_RectGrid
721  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
722  <<": Reading GoTools RectGrid (ClassType="<<ncp<<") not implemented.\n";
723  continue;
724  break;
725  case 710: // Class_BoundedVolume
726  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
727  <<": Reading GoTools BoundedVolume (ClassType="<<ncp<<") not implemented.\n";
728  continue;
729  break;
730  case 720: // Class_Parallelepiped
731  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
732  <<": Reading GoTools Parallelepiped (ClassType="<<ncp<<") not implemented.\n";
733  continue;
734  break;
735  case 721: // Class_SphereVolume
736  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
737  <<": Reading GoTools SphereVolume (ClassType="<<ncp<<") not implemented.\n";
738  continue;
739  break;
740  case 722: // Class_CylinderVolume
741  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
742  <<": Reading GoTools CylinderVolume (ClassType="<<ncp<<") not implemented.\n";
743  continue;
744  break;
745  case 723: // Class_ConeVolume
746  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
747  <<": Reading GoTools ConeVolume (ClassType="<<ncp<<") not implemented.\n";
748  continue;
749  break;
750  case 724: // Class_TorusVolume
751  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
752  <<": Reading GoTools TorusVolume (ClassType="<<ncp<<") not implemented.\n";
753  continue;
754  break;
755  case 793: // Class_LRSplineVolume
756  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
757  <<": Reading GoTools LRSplineVolume (ClassType="<<ncp<<") not implemented.\n";
758  continue;
759  break;
760  default:
761  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
762  <<": Unknown GoTools entity (ClassType="<<ncp<<").\n";
763  continue;
764  break;
765  }
766 
767  // Read Geometry dimension and type
768  getline(file, line);
769  while (!file.eof() && line == "") getline(file, line);
770  lnstream.clear();
771  lnstream.str(line);
772  lnstream >> std::ws >> geoDim >> std::ws >> rational >> std::ws ;
773 
774  g = internal::makeNode("Geometry", *data);
775  if (parDim==1)
776  {
777  g->append_attribute( internal::makeAttribute("type",
778  (rational ? "Nurbs" : "BSpline"), *data) );
779  }
780  else
781  {
782  g->append_attribute( internal::makeAttribute("type",
783  (rational ? "TensorNurbs" : "TensorBSpline")+internal::to_string(parDim), *data) );
784  }
785 
786  data->appendToRoot(g);
787  src = internal::makeNode("Basis", *data);
788  if (parDim>1)
789  src->append_attribute( internal::makeAttribute("type",
790  "TensorBSplineBasis"+internal::to_string(parDim), *data) );
791 
792  if ( rational )
793  {
794  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
795  <<": RATIONAL GoTools input is not supported/tested/working.\n";
796  // Rational tensor basis
797  gsXmlNode* rtb = internal::makeNode("Basis", *data);
798  rtb->append_attribute( internal::makeAttribute("type",
799  (parDim==1 ? "NurbsBasis" : "TensorNurbsBasis"+internal::to_string(parDim)), *data) );
800  rtb->append_node(src);
801  g->append_node(rtb);
802  }
803  else
804  {
805  g->append_node(src);
806  }
807 
808  ncp = 1;
809  for (int i=0; i<parDim; ++i)
810  {
811  // Get numCoeffs_i, order_i
812  getline(file, line);
813  while (!file.eof() && line == "") getline(file, line);
814  lnstream.clear();
815  lnstream.str(line);
816  // Reading the degree
817  lnstream >> std::ws >> c >> std::ws >> deg >> std::ws ;
818  deg--;
819  ncp *= c;
820 
821  // Reading a coordinate-wise basis (knot-vector)
822  getline(file, line);
823  while (!file.eof() && line == "") getline(file, line);
824  lnstream.clear();
825  lnstream.str(line);
826  gsXmlNode* b;
827  if (parDim > 1)
828  {
829  b = internal::makeNode("Basis", *data);
830  b->append_attribute( internal::makeAttribute("index", i, *data) );
831  }
832  else
833  b = src;
834 
835  b->append_attribute( internal::makeAttribute("type", "BSplineBasis", *data) );
836  gsXmlNode* k = internal::makeNode("KnotVector", lnstream.str(), *data);
837  k->append_attribute( internal::makeAttribute("degree", deg, *data) ) ;
838  b->append_node(k);
839  if (parDim > 1)
840  src->append_node(b);
841  }
842 
843  // w, w*cp_x, w*cp_y, w*cp_z: coordinates of the weighted control points (rational)
844  // otherwise
845  // cp_x, cp_y, cp_z: coordinates of the control points (non-rational)
846  // The control points are numbered in a reverse lexicographic order
847  std::ostringstream coefstream;
848 
849  for (int i = 0; i < ncp; i++) // Assumes each coefficient on a new line
850  {
851  if ( getline(file, line) )
852  {
853  while (!file.eof() && line == "") getline(file, line);
854  coefstream << line.substr(0,line.size()) << std::endl;
855  }
856  else
857  {
858  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
859  <<": Failed to read coefficients.\n";
860  return false;
861  }
862  }
863  src = internal::makeNode("coefs", *data);
864  src->value( internal::makeValue( coefstream.str(), *data) );
865  src->append_attribute( internal::makeAttribute("geoDim", geoDim, *data ) );
866  g->append_node(src);
867  }
868 
869  return true;
870 }
871 
872 //template<class T>
873 //bool gsFileData<T>::readGoToolsSpline(gsXmlNode * node )
874 //{ }
875 //template<class T>
876 //bool gsFileData<T>::readGoToolsTrimSurf(gsXmlNode * node )
877 //{ }
878 
879 /*---------- GeoPdes txt file */
880 
881 template<class T>
882 bool gsFileData<T>::readGeompFile( String const & fn )
883 {
884  //Input file
885  std::ifstream file(fn.c_str(),std::ios::in);
886  if ( file.fail() )
887  { gsWarn<<"gsFileData: Problem with file "<<fn<<": Cannot open file stream.\n"; return false; }
888 
889  std::istringstream lnstream;
890  lnstream.unsetf(std::ios_base::skipws);
891 
892  std::stringstream str;
893 
894  String line;
895  //int patch_count(0);
896 
897  int N,Np,Ni(0),Ns(0);
898  std::vector<gsKnotVector<T> *> knots;
899  T tmp;
900 
901  //Parsing file
902  while (!file.eof() && getline(file, line))
903  // ind = line.find_first_not_of(' ');
904  if (line[0] != '#') break;
905 
906  if (file.eof())
907  {
908  gsWarn<<"gsFileData: Problem with file "<<fn<<": Reached end of file.\n";
909  return false;
910  }
911 
912  // N : dimension of the geometry
913  // Np: number of patches to construct the geometry
914  // Ni: total number of interfaces, each one connecting two patches
915  // Ns: total number of subdomains, formed by the union of patches
916  lnstream.clear();
917  lnstream.str(line);
918  lnstream >> std::ws >> N >> std::ws >> Np >> std::ws ;
919  if (Np>1)
920  lnstream >> std::ws >> Ni >> std::ws >> Ns >> std::ws ;
921 
922  // Start id by 1, to match numbering in GeoPDEs file:
923  //max_id=0;
924 
925  gsXmlNode* g;
926 
927  //gsDebug<<"Reading N="<<N<<" and Np="<< Np <<"\n";
928  gsVector<int> p(N);
929  gsVector<int> ncp(N);
930  bool patch(true);
931  String bdr, ifc;
932 
933  while ( !file.eof() ) // Read next line
934  {
935  while (!file.eof() && getline(file, line))
936  if ( line[0] != '#' ) break;
937 
938  // lnstream.clear();
939  // lnstream.str(line);
940  // if ( ! isdigit(line[0]) )
941  // lnstream >> token;
942 
943  std::transform(line.begin(),line.end(),line.begin(),::tolower);
944  //gsDebug<< "token=\""<<token<<"\"\n";
945 
946  if ( line == "" )// avoid empty lines
947  {
948  continue;
949  }
950  /* //Note: no need to read topology
951  else if ( line.find("interface")!=String::npos )
952  {
953  while (!file.eof() && getline(file, line))
954  if (line[0] != '#') break;
955  ifc.append(line);
956  while (!file.eof() && getline(file, line))
957  if (line[0] != '#') break;
958  ifc.append(" ");
959  ifc.append(line);
960  while (!file.eof() && getline(file, line))
961  if (line[0] != '#') break;
962  ifc.append(" ");
963  ifc.append(line);
964  ifc.append("\n");
965  patch=false;
966  }
967  else if ( line.find("boundary")!=String::npos )
968  {
969  while (!file.eof() && getline(file, line))
970  if (line[0] != '#') break;
971  // getting number of sides
972  int nb;
973  lnstream.clear();
974  lnstream.str(line) ;
975  lnstream >> std::ws >> nb;
976  for ( int i = 0; i<nb; ++i)
977  {
978  while (!file.eof() && getline(file, line))
979  if (line[0] != '#') break;
980  bdr.append(line);
981  bdr.append(" ");
982  patch=false;
983  }
984  }
985  */
986  else if ( ( line.find("patch")!=String::npos ) || patch==true )
987  {
988  // gsDebug <<"Patch "<< line <<"\n";
989  //GISMO_ASSERT( patch_count++ < Np, "Something went wrong while reading GeoPDEs file." );
990 
991  // p(i): the degree in each Cartesian direction (N integers)
992  if ( ! isdigit(line[0]) )
993  while (!file.eof() && getline(file, line))
994  if (line[0] != '#') break;
995  lnstream.clear();
996  lnstream.str(line) ;
997  for (int i=0;i<N;++i)
998  lnstream >> std::ws >> p[i] ;
999  //gsDebug<<"Reading degrees OK "<< p.transpose() <<"\n";
1000 
1001  // ncp(i): the number of control points in each direction (N integers)
1002  while (!file.eof() && getline(file, line))
1003  if (line[0] != '#') break;
1004  lnstream.clear();
1005  lnstream.str(line);
1006  for (int i=0;i<N;++i)
1007  lnstream >> std::ws >> ncp[i] ;
1008  unsigned sz= ncp.prod() ;
1009  //gsDebug<<"Reading ncps OK "<< ncp.transpose() <<"\n";
1010 
1011  g = internal::makeNode("Geometry", *data);
1012  g->append_attribute( internal::makeAttribute("type", "TensorNurbs"+internal::to_string(N), *data) );
1013  data->appendToRoot(g);
1014 
1015  // Rational tensor basis
1016  gsXmlNode* rtb = internal::makeNode("Basis", *data);
1017  rtb->append_attribute( internal::makeAttribute("type", "TensorNurbsBasis"+internal::to_string(N), *data) );
1018  g->append_node(rtb);
1019 
1020  // Read source basis
1021  gsXmlNode* src = internal::makeNode("Basis", *data);
1022  rtb->append_node(src);
1023 
1024  if (N==1)
1025  {
1026  src->append_attribute( internal::makeAttribute("type", "NurbsBasis", *data) );
1027  while (!file.eof() && getline(file, line))
1028  if (line[0] != '#') break;
1029  lnstream.clear();
1030  lnstream.str(line);
1031  gsXmlNode* k = internal::makeNode("KnotVector", lnstream.str(), *data);
1032  k->append_attribute( internal::makeAttribute("degree", p[0], *data ) ) ;
1033  src->append_node(k);
1034  }
1035  else // N>1
1036  {
1037  src->append_attribute( internal::makeAttribute("type", "TensorBSplineBasis"+internal::to_string(N), *data) );
1038  //src->append_attribute( internal::makeAttribute("parDim", N, *data ) );
1039  for (int i=0;i<N;++i)
1040  {
1041  while (!file.eof() && getline(file, line))
1042  if (line[0] != '#') break;
1043  lnstream.clear();
1044  lnstream.str(line);
1045  gsXmlNode* b = internal::makeNode("Basis", *data);
1046  b->append_attribute( internal::makeAttribute("type", "BSplineBasis", *data) );
1047  b->append_attribute( internal::makeAttribute("index", i, *data) );
1048  src->append_node(b);
1049  gsXmlNode* k = internal::makeNode("KnotVector", lnstream.str(), *data);
1050  k->append_attribute( internal::makeAttribute("degree", p[i], *data) ) ;
1051  b->append_node(k);
1052  }
1053  }
1054 
1055  // cp_x, cp_y, cp_z: coordinates of the weighted control points
1056  // (see Section 4.2 of The NURBS Book, L. Piegl & W. Tiller)
1057  // (N rows, each one with prod_{i=1}^{N} ncp(i) float values)
1058  // The control points are numbered in a reverse lexicographic order
1059  gsMatrix<T> coefs(sz,N ) ;
1060  for (int i=0;i<N;++i)
1061  {
1062  while (!file.eof() && getline(file, line))
1063  if (line[0] != '#') break;
1064  lnstream.clear();
1065  lnstream.str(line);
1066  for (unsigned k=0;k< sz;++k)
1067  {
1068  lnstream >> std::ws >> tmp ;
1069  coefs(k,i) = tmp ;
1070  }
1071  }
1072  //gsDebug<<"Reading coefs OK\n"<< *coefs <<"\n";
1073 
1074  // weights: weight associated to each basis function (or control point)
1075  // (prod(ncp ) float values)
1076  gsMatrix<T> weights(sz,1) ;
1077  while (!file.eof() && getline(file, line))
1078  if (line[0] != '#') break;
1079  lnstream.clear();
1080  lnstream.str(line);
1081  for (unsigned k=0;k< sz;++k)
1082  {
1083  lnstream >> std::ws >> tmp ;
1084  weights(k,0) = tmp ;
1085  coefs.row(k) /= tmp; //Divide weighted coeffient by the weight
1086  }
1087  //gsDebug<<"Reading weights OK\n"<< *weights <<"\n";
1088 
1089  // if ( weights == gsMatrix<T>::Ones(sz,1) )
1090  // gsDebug<<"gsFileData: In fact weights are all equal to 1.\n";
1091 
1092  gsXmlNode* c = internal::makeNode("weights", weights, *data, true);
1093  rtb->append_node(c);
1094 
1095  c = internal::makeNode("coefs", coefs, *data, false);
1096  c->append_attribute( internal::makeAttribute("geoDim", N, *data ) );
1097  g->append_node(c);
1098  }
1099  }
1100 
1101  /*
1102  // Note: no need to read multipatch structure
1103  if ( Np > 1 )
1104  {
1105  g = internal::makeNode("MultiPatch", *data);
1106  g->append_attribute( internal::makeAttribute("parDim",N, *data) );
1107  parent->append_node(g);
1108  str.clear();
1109  str << 1 <<" "<< Np;
1110  gsXmlNode* c = internal::makeNode("patches", str.str(), *data);
1111  c->append_attribute( internal::makeAttribute("type","id_range", *data) );
1112  g->append_node(c);
1113 
1114  c = internal::makeNode("interfaces", ifc, *data);
1115  g->append_node(c);
1116  c = internal::makeNode("boundary",bdr, *data);
1117  g->append_node(c);
1118  }
1119  */
1120  return true;
1121 };
1122 
1123 /*---------- SurfLab/BezierView */
1124 
1125 /*
1126  template<class T>
1127  bool gsFileData<T>::readBezierView( String const & fn )
1128  {
1129  //Input file
1130  std::ifstream file(fn.c_str(),std::ios::in);
1131  if ( !file.good() )
1132  {gsWarn<<"gsFileData: Problem with file "<<fn<<": Cannot open file stream.\n"; return false; }
1133 
1134  std::istringstream lnstream;
1135  lnstream.unsetf(std::ios_base::skipws);
1136 
1137  String line;
1138 
1139  //Note: patch kind/type definitions
1140  // #define POLY 1 // polyhedron
1141  // #define TRIANG 3 // triangular patch
1142  // #define TP_EQ 4 // tensorproduct with same degree in both dir.
1143  // #define TP 5 // general tensorproduct
1144  // #define TRIM_CURVE 6
1145  // #define TP_BSP 7 // general b-spline tensorproduct
1146  // #define RATIONAL 8 probably rational tensor product Bezier patch
1147  // #define PNTRI 9 // PN triangle patch, containing points and normals
1148  // #define PNTP 10 // PN quads patch, containing points and normals
1149  int kind;
1150 
1151  char string[255];
1152  int degu, degv, num_normals = 0, num_points;
1153 
1154  gsXmlNode* parent = data->first_node("xml") ;
1155  // Node for a Geometry object
1156  gsXmlNode * g;
1157  // Node for a basis object
1158  gsXmlNode * src;
1159 
1160  while (!file.eof() )
1161  {
1162  // skip group ids
1163  while (!file.eof() && getline(file, line))
1164  if ( line.find("group")!=String::npos ||
1165  line.find("Group")!=String::npos )
1166  break;
1167 
1168  // get kind/type
1169  lnstream.clear();
1170  lnstream.str(line) ;
1171  lnstream >> std::ws >> kind >> std::ws ;
1172 
1173  switch (kind) :
1174  {
1175  case 4 :
1176  case 8 :
1177  case 10:
1178  case 5:
1179 
1180  // read degrees
1181  lnstream >> std::ws >> degu >> std::ws ;
1182  if(kind==5)
1183  degv = degu;
1184  else
1185  lnstream >> std::ws >> degv >> std::ws ;
1186 
1187  if(kind==10)
1188  {
1189  int Ndegu, Ndegv;
1190  lnstream >> std::ws >> Ndegu >> std::ws >> Ndegv >> std::ws ;
1191  num_normals = 3 * (Ndegu+1)*(Ndegv+1);
1192  }
1193 
1194  num_points = (degu+1)*(degv+1);
1195  points_dim = (kind==8 ? 4 : 3);
1196 
1197  // read in all control points
1198  gsMatrix<T> coefs(num_points, points_dim);
1199  for (i=0;i<num_points;i++)
1200  {
1201  lnstream.clear();
1202  lnstream.str(line);
1203  for (int j=0;i<points_dim;++k)
1204  lnstream >> std::ws >> coefs(i,k) ;
1205  }
1206 
1207  if(kind==10)
1208  for (i=0;i<num_normals;i++)
1209  sstr.ignore(128, std::ws);
1210 
1211  if(kind==8) // 4D control points
1212  {
1213  gsMatrix<T> weights = coefs.row(3);
1214  coefs.resize(gsEigen::NoChange,3);
1215  gsDebug<<"weights: "<< weights.transpose() <<"\n";
1216  }
1217 
1218  g = internal::makeNode("Geometry", *data);
1219  src = internal::makeNode("Basis", *data);
1220  g->append_node(src);
1221  gsXmlNode* b = internal::makeNode("coefs", coefs, *data, true);
1222  g->append_node(b);
1223 
1224  src->append_attribute( internal::makeAttribute("type", "TensorBSplineBasis2", *data) );
1225 
1226  String kv(4*degv+3,' ');
1227  for (i=0;i<degv+1;i++)
1228  [
1229  kv[2*i] = '0';
1230  }
1231 
1232  b = internal::makeNode("Basis", *data);
1233  b->append_attribute( internal::makeAttribute("type", "BSplineBasis", *data) );
1234  b->append_attribute( internal::makeAttribute("index", 0, *data) );
1235  b = internal::makeNode("KnotVector", lnstream.str(), *data);
1236  b->append_attribute( internal::makeAttribute("degree", degu, *data) ) ;
1237 
1238  src->append_node(b);
1239  b = internal::makeNode("Basis", *data);
1240  b->append_attribute( internal::makeAttribute("type", "BSplineBasis", *data) );
1241  b->append_attribute( internal::makeAttribute("index", 1, *data) );
1242  src->append_node(b);
1243 
1244  break;
1245 
1246  case 3 : // Triangular patch
1247  case 10:
1248 
1249  default:
1250  break;
1251  }
1252  }
1253  }
1254 */
1255 
1256 /*---------- OFF mesh from .off file */
1257 
1258 template<class T>
1259 bool gsFileData<T>::readOffFile( String const & fn )
1260 {
1261  //https://stackoverflow.com/questions/47125387/stringstream-and-binary-data
1262  //std::istringstream buffer;
1263  //buffer << file.rdbuf();
1264 
1265  //https://stackoverflow.com/questions/38874200/trying-to-replace-scanf-with-sstream
1266 
1267  /* //verb-read
1268  std::ifstream buffer(fn);
1269  std::ostringstream bb; bb << buffer.rdbuf();
1270  gsXmlNode* m = internal::makeNode("SurfMesh", *data);
1271  m->append_attribute( internal::makeAttribute("type", "off", *data) );
1272  m->value( internal::makeValue( bb.str(), *data) );
1273  data->appendToRoot(m);
1274  return true;
1275  */
1276 
1277  //Input file
1278  std::ifstream file(fn.c_str(),std::ios::in);
1279  if ( !file.good() )
1280  { gsWarn<<"gsFileData: Problem with file "<<fn<<": Cannot open file stream.\n"; return false; }
1281 
1282  gsXmlNode* g = internal::makeNode("Mesh", *data);
1283  g->append_attribute( internal::makeAttribute("type", "off", *data) );
1284  data->appendToRoot(g);
1285 
1286  String line;
1287  std::istringstream lnstream;
1288  lnstream.unsetf(std::ios_base::skipws);
1289  std::ostringstream tmp;
1290 
1291  getline(file, line);
1292  if ( line.compare(0,3,"OFF") != 0)
1293  return false;
1294 
1295  getline(file, line);
1296  int nverts, nfaces, nedges(0);
1297  lnstream.str(line);
1298  lnstream >> std::ws >> nverts >>
1299  std::ws >> nfaces >>
1300  std::ws >> nedges ;
1301 
1302  g->append_attribute( internal::makeAttribute("vertices", nverts, *data) );
1303  g->append_attribute( internal::makeAttribute("faces" , nfaces, *data) );
1304  g->append_attribute( internal::makeAttribute("edges" , nedges, *data) );
1305 
1306  for (int i = 0; i < nverts; i++)
1307  if ( getline(file, line) )
1308  tmp << line.substr(0,line.size()) << std::endl;
1309  else
1310  return false;
1311 
1312  for (int i = 0; i < nfaces; i++)
1313  if ( getline(file, line) )
1314  tmp << line.substr(0,line.size()) << std::endl;
1315  else
1316  return false;
1317 
1318  g->value( internal::makeValue( tmp.str(), *data) );
1319  tmp.clear();
1320 
1321  return true;
1322 }
1323 
1324 /*---------- STL mesh file */
1325 
1326 template<class T>
1327 bool gsFileData<T>::readStlFile( String const & fn )
1328 {
1329  bool solid(false),facet(false),loop(false);
1330  //Input file
1331  std::ifstream file(fn.c_str(),std::ios::in);
1332  if ( !file.good() )
1333  { gsWarn<<"gsFileData: Problem with file "<<fn<<": Cannot open file stream.\n"; return false; }
1334 
1335  gsXmlNode* g = internal::makeNode("Mesh", *data);
1336  g->append_attribute( internal::makeAttribute("type", "off", *data) );
1337  data->appendToRoot(g);
1338 
1339  std::ostringstream triangles;
1340  triangles.unsetf(std::ios_base::skipws);
1341  std::ostringstream vertices;
1342  vertices.unsetf(std::ios_base::skipws);
1343  unsigned nvert(0), nfaces(0), tmp(0);
1344 
1345  unsigned lineNumber(0);
1346  std::string str;
1347 
1348  while( !file.eof() && getline(file, str) )
1349  {
1350  std::transform(str.begin(),str.end(),str.begin(),::tolower);
1351  if(str.find("solid")!=String::npos && str.find("endsolid")==String::npos)
1352  {
1353  if(solid) ioError(lineNumber,"startSolid");
1354  solid=true;
1355  }
1356  else if(str.find("endsolid")!=String::npos)
1357  {
1358  if(!solid || facet || loop) ioError(lineNumber,"endSolid");
1359  solid=false;
1360  }
1361  else if(str.find("facet")!=String::npos && str.find("endfacet")==String::npos)
1362  {
1363  if(!solid || facet || loop) ioError(lineNumber,"startFacet");
1364  facet=true;
1365  }
1366  else if(str.find("endfacet")!=String::npos)
1367  {
1368  if(!solid || !facet || loop) ioError(lineNumber,"endFacet");
1369  facet=false;
1370  }
1371  else if(str.find("outer")!=String::npos)
1372  {
1373  if(!solid || !facet || loop) ioError(lineNumber,"startLoop");
1374  loop=true;
1375  }
1376  else if(str.find("endloop")!=String::npos)
1377  {
1378  if(!solid || !facet || !loop )
1379  ioError(lineNumber,"endLoop");
1380  triangles<< tmp;
1381  for (unsigned i= nvert-tmp; i!=nvert; ++i)
1382  triangles<<" "<< i;
1383  triangles<<"\n";
1384  nfaces++;
1385  loop=false;
1386  tmp = 0;
1387  }
1388  else if(str.find("vertex")!=String::npos)
1389  {
1390  if(!solid || !facet || !loop )
1391  ioError(lineNumber,"vertex");
1392  tmp++;
1393  nvert++;
1394  size_t pos=str.rfind("vertex")+7;
1395  assert(pos!=String::npos);
1396  vertices << str.substr(pos, str.size()-pos) <<"\n";
1397  }
1398  }
1399 
1400  g->append_attribute( internal::makeAttribute("vertices", nvert, *data) );
1401  g->append_attribute( internal::makeAttribute("faces" , nfaces, *data) );
1402  vertices << triangles.str() ;
1403  g->value( internal::makeValue( vertices.str(), *data) );
1404 
1405  return true;
1406 }
1407 
1408 
1409 template<class T>
1410 bool gsFileData<T>::readObjFile( String const & fn )
1411 {
1412  GISMO_UNUSED(fn);
1413  //gsWarn<<"Assuming Linux file, please convert dos2unix first.\n";
1414 
1415  //Input file
1416  std::ifstream file(fn.c_str(),std::ios::in);
1417  if ( !file.good() )
1418  { gsWarn<<"gsFileData: Problem with file "<<fn<<": Cannot open file stream.\n"; return false; }
1419 
1420 /*
1421 // -- mesh start
1422  std::string s;
1423  while(file>>s)
1424  {
1425  switch(*s.c_str())
1426  {
1427  case 'v':
1428  {
1429  vertex v;
1430  file>>v.x>>v.y>>v.z;
1431  this->vertices.push_back(v);
1432  }
1433  break;
1434  case 'f':
1435  {
1436  face f;
1437  file>>f.v1>>f.v2>>f.v3;
1438  faces.push_back(f);
1439  }
1440  break;
1441  default:
1442  break;
1443  }
1444  }
1445 //-- mesh end
1446 */
1447 #if FALSE
1448 
1449  std::istringstream lnstream;
1450  lnstream.unsetf(std::ios_base::skipws);
1451 
1452  String token(" "), bdr, ifc;
1453 
1454  //Parsing file
1455  while (!file.eof() && getline(file, line))
1456  {
1457  lnstream.clear();
1458  lnstream.str(line);
1459  lnstream >> std::ws;
1460  if (lnstream.eof())
1461  continue;
1462  else if (lnstream.peek() == '#')
1463  continue;
1464  else {
1465  lnstream >> token;
1466 
1467  //vertex (v)
1468  if (token == "v")
1469  {
1470  double x;
1471  Vertex v;
1472  while (lnstream && !lnstream.eof())
1473  {
1474  lnstream >> std::ws >> x >> std::ws ;
1475  v.push_back(x);
1476  }
1477  points.push_back(v);
1478  }
1479  //vertex (vp)
1480  else if (token == "vp")
1481  {
1482  double x;
1483  Vertex v;
1484  while (lnstream && !lnstream.eof())
1485  {
1486  lnstream >> std::ws >> x >> std::ws ;
1487  v.push_back(x);
1488  }
1489  points2d.push_back(v);
1490  }
1491  else if (token == "cstype")
1492  {
1493  lnstream >>std::ws >> cstype >> std::ws;
1494  std::string t;
1495  while (lnstream && !lnstream.eof())
1496  {
1497  lnstream >> std::ws >> t >> std::ws ;
1498  cstype+= "_"+ t;
1499  //gsDebug<<"File has a "<<cstype<<std::endl;
1500  }
1501  }
1502  else if (token == "deg")
1503  {
1504  lnstream >> std::ws >> du >> std::ws >> dv>> std::ws;
1505  gsDebug<<"du, dv: "<<du<<", "<<dv <<std::endl;
1506  }
1507  else if (token == "curv")
1508  {
1509  type="";
1510  cstype="";
1511  gsWarn<<"gsFileData: Problem with file "<<fn<<": Ignore curv.\n";
1512 
1513  continue;
1514  }
1515  else if (token == "curv2")
1516  {
1517  c2 = new curv2();
1518  c2->deg= du;
1519  int cp;
1520  type=token;
1521 
1522  while (lnstream && !lnstream.eof())
1523  {
1524  lnstream >> std::ws >> cp ;
1525  //gsDebug<<"control point2d_"<< cp<< " is "<< (points2d[cp-1])[0] <<std::endl;
1526  c2->control_points.push_back(cp-1);
1527  }
1528  //cstype="";
1529 
1530  continue;
1531  }
1532  else if (token == "surf")
1533  {
1534  surf_count++;
1535  int cp;
1536  type=token;
1537  lnstream >> std::ws >> start_u >> std::ws >> end_u;
1538  lnstream >> std::ws >> start_v >> std::ws >> end_v;
1539  while (lnstream && !lnstream.eof())
1540  {
1541  lnstream >> std::ws >> cp ;
1542  //gsDebug<<"control point_"<< cp<< " is "<< (points[cp-1])[0] <<std::endl;
1543  control_points.push_back(cp-1);
1544  }
1545  }
1546  else if (token == "parm")
1547  {
1548  char c;
1549  double val;
1550  lnstream >> std::ws >> c >> std::ws;
1551 
1552  while (lnstream && !lnstream.eof())
1553  {
1554  lnstream >> std::ws >> val >> std::ws;
1555  //gsDebug<<"knot_"<<c<<": "<<val <<std::endl;
1556  if (type == "curv2")
1557  c2->knots.push_back(val);
1558  else
1559  knots[var[c]].push_back(val);
1560  }
1561 
1562  }
1563  else if (token == "trim")// trim loop
1564  {
1565  double u,v;
1566  int cv;
1567  trim_loop t;
1568 
1569  while (lnstream && !lnstream.eof())
1570  {
1571  lnstream >> std::ws >> u >> std::ws >> v >> std::ws >> cv >> std::ws;
1572  t.push_back(cv);
1573  }
1574 
1575  gsWarn<<"gsFileData: Problem with file "<<fn<<": Ignore trim loop.\n";
1576  }
1577  else if (token == "end")//always in the end
1578  {
1579  gsDebug<<"End reading "<< cstype <<" "<<type<<std::endl;
1580 
1581  if (cstype=="bspline" && type=="surf")
1582  {
1583  curves.push_back(c2);
1584  }
1585 
1586 
1587  if ( trims.size() )
1588  axl<<"<surface type=\"trimmed\" number =\"1\">\n";
1589 
1590  //output spline
1591  if (cstype=="bspline" && type=="surf")
1592  {
1593  axl<<"<surface type=\"bspline\" name=\"bs_"<<surf_count<<"\">\n";
1594  axl<<"<dimension>3</dimension>\n";
1595  axl<<"<number>"<<knots[0].size()-du-1 <<" "<<knots[1].size()-dv-1<<"</number>\n";
1596  axl<<"<order>"<<du+1<<" "<<dv+1<<"</order>\n";
1597  axl<<"<knots>";
1598  for (int i=0; i<knots[0].size(); i++ )
1599  axl<< knots[0][i]<< " ";
1600  axl<<"</knots>\n";
1601  axl<<"<knots>";
1602  for (int i=0; i<knots[1].size(); i++ )
1603  axl<< knots[1][i]<< " ";
1604  axl<<"</knots>\n";
1605  axl<<"<points>\n";
1606  for (int i=0; i<control_points.size(); i++ )
1607  {
1608  for (int j=0; j<points[control_points[i]].size(); j++ )
1609  axl<< points[control_points[i]][j] << " ";
1610  axl << "\n";
1611  }
1612  axl<<"</points>\n";
1613  axl<< "</surface>\n";
1614  gsDebug<<"Got "<< cstype <<" "<<type<<" "<<surf_count<<std::endl;
1615  }
1616  else if (cstype=="rat_bspline" && type=="surf")
1617  {
1618  axl<<"<surface type=\"bspline\" rational=\"1\" name=\"bs_"<<surf_count<<"\">\n";
1619  axl<<"<dimension>3</dimension>\n";
1620  axl<<"<number>"<<knots[0].size()-du-1 <<" "<<knots[1].size()-dv-1<<"</number>\n";
1621  axl<<"<order>"<<du+1<<" "<<dv+1<<"</order>\n";
1622  axl<<"<knots>";
1623  for (int i=0; i<knots[0].size(); i++ )
1624  axl<< knots[0][i]<< " ";
1625  axl<<"</knots>\n";
1626  axl<<"<knots>";
1627  for (int i=0; i<knots[1].size(); i++ )
1628  axl<< knots[1][i]<< " ";
1629  axl<<"</knots>\n";
1630  axl<<"<points>\n";
1631  for (int i=0; i<control_points.size(); i++ )
1632  {
1633  // RATIONAL ?
1634  for (int j=0; j<points[control_points[i]].size()-1; j++ )
1635  {
1636  //gsWarn<<"ok "<< j <<std::endl;
1637  axl<< points[control_points[i]][j] << " ";
1638  }
1639  //if (j==4) axl<<1;
1640  axl << "\n";
1641  }
1642  axl<<"</points>\n";
1643 //
1644 
1645 
1646  for (int i=0; i<trims.size(); i++ )
1647  {
1648  axl<< "<curveloop>\n";
1649  for (int j=0; j<trims[i].size(); j++ )
1650  {
1651 // write_curve( axl, trims[i][j] );
1652  }
1653  axl<< "</curveloop>\n";
1654  }
1655 
1656 //
1657  axl<< "</surface>\n";
1658 
1659  gsDebug<<"Got "<< cstype <<" "<<type<<" "<<surf_count<<std::endl;
1660  }
1661  else if (cstype=="bspline" && type=="curv2")
1662  {
1663 
1664  }
1665  else if (cstype!="")
1666  {
1667  gsWarn<<"gsFileData: Problem with file "<<fn<<": Ignoring "<< cstype<<" "<<type <<std::endl;
1668  }
1669  //if (surf_count==5) break;
1670  //delete knots, degrees, control points
1671  knots.clear();
1672  knots.push_back(Vertex());
1673  knots.push_back(Vertex());
1674  control_points.clear();
1675  trims.clear();
1676  //control_points2d.clear();
1677  type="";
1678  cstype="";
1679  }
1680  else { // unknown token
1681  std::string message = "ignoring line ‘" + line + "’";
1682  }
1683  }
1684  }
1685 
1686 
1687 #endif
1688 
1689  return true;
1690 }
1691 
1692 
1693 template<class T>
1694 bool gsFileData<T>::readBrepFile( String const & fn )
1695 {
1696 #ifdef gsOpenCascade_ENABLED
1697  return extensions::gsReadBrep( fn.c_str(), *data);
1698 #else
1699  GISMO_UNUSED(fn);
1700  return false;
1701 #endif
1702 }
1703 
1704 namespace
1705 {
1706 
1707 #define MAXENTITY 1000 /* maximum number of entities recognised from IGES file */
1708 #define FIELD_L 26 /*length of fixed length field in text file (sign, digits - double float) */
1709 
1710 enum entity_j_name{
1711  E_TYPE= 0,
1712  PD_PTR= 1,
1713  PD_CNT= 2,
1714  ELAYER= 3
1715 };
1716 
1717 int read_iges_line(FILE *f, char *s)
1718 {
1719  /* read filerow from iges*/
1720  int i;
1721  int c;
1722  for (i=0; i < 80; i++)
1723  {
1724  c=getc(f);
1725  if (c == EOF) return -1;
1726  s[i]=(char) c;
1727  if (i==0)
1728  { /* eat CR LF in line beginning and reset "i" to zero */
1729  switch (s[i])
1730  {
1731  case '\x0D': i--; break;
1732  case '\x0A': i--; break;
1733  }
1734  }
1735  }
1736  return 0;
1737 }
1738 
1739 void copy_field(char *s1, int poz, int x, char *s2)
1740 {
1741  /* copy "x" chars from position "poz" from string "s1" to string "s2"*/
1742  int i=poz, j=0;
1743  while (j < x)
1744  {
1745  s2[j]=s1[i];
1746  i++;
1747  j++;
1748  }
1749 }
1750 
1751 void format_number(char *n_s)
1752 {
1753  /* format number string */
1754  int n_len = strlen(n_s);
1755  /* regularize E,e,D,d -> e */
1756  for (int i=0; i < n_len; i++)
1757  {
1758  if(n_s[i] == 'E' || n_s[i] == 'e' || n_s[i] == 'D' || n_s[i] == 'd')
1759  n_s[i]='e';
1760  }
1761  /* eliminate e0 e+0 e-0 e+000 at the end
1762  * cycle from the end - on 'e', move the end, else jump out
1763  * */
1764  if(n_len > 2)
1765  {
1766  if(n_s[n_len - 1] == '0')
1767  {
1768  for (int i=n_len-1; i >= 0; i--)
1769  {
1770  switch (n_s[i])
1771  {
1772  case '0':
1773  case '+':
1774  case '-':
1775  break;
1776  case 'e':
1777  n_s[i]= '\0';
1778  n_len= i;
1779  goto endfor_fn;
1780  default : goto endfor_fn;
1781  }
1782  }
1783  endfor_fn: /* jump out of FOR from inside of SWITCH */
1784  ;
1785  }
1786  }
1787 }
1788 
1789 void parse_d_entry(int entity[MAXENTITY][4], int & emark, int & entity_sum, char *ret1, char *ret2)
1790 {
1791  /* Parse single entry (pair of lines) in D section. */
1792  char fld[9]; /* for reading the value of array */
1793  int kod, pd_ptr, pd_count, layer, form;
1794  fld[8]='\0';
1795  /* Read:
1796  * entity type (A), form (B), pointer to PD line (C), PD count (D), layer (E)
1797  * and if the entity is recognised (406-3,106-2,116,126,128) load it into entity[][]
1798  * */
1799  copy_field(ret1,0,8,fld); kod= atoi(fld); /* A */
1800  copy_field(ret2,32,8,fld); form= atoi(fld); /* B */
1801  copy_field(ret1,8,8,fld); pd_ptr= atoi(fld); /* C */
1802  copy_field(ret2,24,8,fld); pd_count=atoi(fld); /* D */
1803  copy_field(ret1,32,8,fld); layer= atoi(fld); /* E */
1804  GISMO_UNUSED(form);
1805  switch (kod)
1806  {
1807 /*
1808  case 406:
1809  if (form != 3) break; // only layers (406-3)
1810  entity[emark][E_TYPE]=kod;
1811  entity[emark][PD_PTR]=pd_ptr;
1812  entity[emark][PD_CNT]=pd_count;
1813  entity[emark][ELAYER]=layer;
1814  entity_sum++;
1815  emark++;
1816  break;
1817  case 106:
1818  if (o_extract_pt == 0) break;
1819  if (form != 2) break; // only points (106-2)
1820  if (o_extract_unblanked == 1 && ret1[65] == '1') break; // only unblanked !
1821  entity[emark][E_TYPE]=kod;
1822  entity[emark][PD_PTR]=pd_ptr;
1823  entity[emark][PD_CNT]=pd_count;
1824  entity[emark][ELAYER]=layer;
1825  entity_sum++;
1826  emark++;
1827  break;
1828  case 116:
1829  if (o_extract_pt == 0) break;
1830  if (o_extract_unblanked == 1 && ret1[65] == '1') break;
1831  entity[emark][E_TYPE]=kod;
1832  entity[emark][PD_PTR]=pd_ptr;
1833  entity[emark][PD_CNT]=pd_count;
1834  entity[emark][ELAYER]=layer;
1835  entity_sum++;
1836  emark++;
1837  break;
1838 */
1839  case 126:
1840  entity[emark][E_TYPE]=kod;
1841  entity[emark][PD_PTR]=pd_ptr;
1842  entity[emark][PD_CNT]=pd_count;
1843  entity[emark][ELAYER]=layer;
1844  entity_sum++;
1845  emark++;
1846  break;
1847  case 128:
1848  //if (only_extract_unblanked == 1 && ret1[65] == '1') break;
1849  entity[emark][E_TYPE]=kod;
1850  entity[emark][PD_PTR]=pd_ptr;
1851  entity[emark][PD_CNT]=pd_count;
1852  entity[emark][ELAYER]=layer;
1853  entity_sum++;
1854  emark++;
1855  break;
1856  }
1857 }
1858 
1859 void read_iges_pd128(char *s, int begin, std::stringstream & ss)
1860 {
1861  /* read 128 PD in IGES */
1862  static char t[FIELD_L+1];
1863  static int phase; /* 0-header, 1-cps, 2-knots, 3-weights */
1864  static int m; /* marker in strings x, y, z */
1865  static int c, endknot; /* counter of points */
1866  static int q[5],b[4]; /* b[0,1]-maxindex_of_ctrl_pts, b[2,3]-degree_of_Bspl */
1867  //static int sw[5]; /* breaks: 10, +b[0]+b[2]+2, +b[1]+b[3]+2, +(b[0]+1)*(b[1]+1), +(b[0]+1)*(b[1]+1) */
1868  int i; /* i-order of the character */
1869  static int j; /* j-order of head. */
1870  if (begin == 1)
1871  {
1872  phase=0;
1873  c=0;
1874  m=0;
1875  j=0;
1876  //sw[0]=10;
1877  }
1878  for (i=0; i <= 64; i++)
1879  {
1880  switch (phase)
1881  {
1882  case 0: // PHASE header
1883  switch (j)
1884  {
1885  case 1:
1886  case 2:
1887  case 3:
1888  case 4:
1889  if (s[i] == ',')
1890  {
1891  t[m]='\0';
1892  b[j-1]=atoi(t);
1893  j++; m=0;
1894  }
1895  else
1896  { t[m]=s[i]; m++; }
1897  break;
1898  default: //j=0, 5..9
1899  if (s[i] == ',')
1900  {
1901  // j=0: 128
1902  //(j=1..4: data in b[] )
1903  // 5 integer parameters:
1904  // j=5: closed in first direction
1905  // j=6: closed in second direction
1906  // j=7: rational
1907  // j=8: periodic in first direction
1908  // j=9: periodic in second direction
1909 
1910  // b[0]+b[2]+2 u-knots
1911  // b[1]+b[2]+2 v-knots
1912  // (b[0]+1)*(b[1]+1) weights
1913  // control points
1914  t[m]= '\0';
1915  m= 0;
1916  //printf("%d: Got number: %s\n", j, t);
1917  if (0!=j) q[j-5]= atoi(t);
1918  if (7==j) ss<<q[0]<<",";
1919  j++;
1920  }
1921  else
1922  { /* digit + - E e D d */
1923  t[m]= s[i];
1924  m++;
1925  break;
1926  }
1927  if ( 10 == j )
1928  {
1929  endknot = b[0]+b[2]+2+b[1]+b[3]+2;
1930  phase=1; // knots start
1931  }
1932  }
1933  break;
1934  case 3: // PHASE CP
1935  if (s[i] == ' ') return;
1936  else if (s[i] == ',' || s[i] == ';') /* the last coordinate */
1937  {
1938  t[m]='\0';
1939  format_number(t);
1940  ss <<" "<< t;
1941  m= 0;
1942  c++;
1943  if (c == 3*(b[0]+1)*(b[1]+1))
1944  {
1945  c=0;
1946  return;
1947  }
1948  }
1949  else
1950  { /* digit + - E e D d */
1951  t[m]= s[i];
1952  m++;
1953  }
1954  break;
1955  case 1: // PHASE knots
1956  if (s[i] == ' ') return;
1957  else if (s[i] == ',')
1958  { /* next knot */
1959  t[m]= '\0';
1960  format_number(t);
1961  ss <<" "<< t;
1962  m= 0;
1963  c++;
1964  if (c == b[0]+b[2]+2) ss<<","<<b[2]<<",";
1965  }
1966  else { /* digit + - E e D d */
1967  t[m]= s[i];
1968  m++;
1969  break;
1970  }
1971 
1972  if (c == endknot)
1973  {
1974  ss<<","<<b[3]<<",";
1975  c=0;
1976  phase=2; //weights start
1977  }
1978  break;
1979  case 2: // PHASE weights
1980  if (s[i] == ' ') return;
1981  else if (s[i] == ',')
1982  { /* next knot */
1983  t[m]= '\0';
1984  format_number(t);
1985  ss <<" "<< t;
1986  m= 0;
1987  c++;
1988  }
1989  else { /* digit + - E e D d */
1990  t[m]= s[i];
1991  m++;
1992  break;
1993  }
1994 
1995  if (c == (b[0]+1)*(b[1]+1))
1996  {
1997  ss<<",";
1998  c=0;
1999  phase=3; //control points start
2000  }
2001  break;
2002  }
2003  }
2004 }
2005 
2006 void read_iges_pd126(char *s, int begin, std::stringstream & ss)
2007 {
2008  /* read 126 PD in IGES */
2009  static char t[FIELD_L+1];
2010  static int phase; /* 0-header, 1-cps, 2-knots, 3-weights */
2011  static int m; /* marker in strings x, y, z */
2012  static int c, endknot; /* counter of points */
2013  static int b[2]; /* b[0]-maxindex_of_ctrl_pts, b[1]-degree_of_Bspl */
2014  int i; /* i-order of the character */
2015  static int j; /* j-order of head. */
2016  if (begin == 1)
2017  {
2018  phase=0;
2019  c=0;
2020  m=0;
2021  j=0;
2022  }
2023  for (i=0; i <= 64; i++)
2024  {
2025  switch (phase)
2026  {
2027  case 0: // PHASE header
2028  switch (j)
2029  {
2030  case 1:
2031  case 2:
2032  if (s[i] == ',')
2033  {
2034  t[m]='\0';
2035  b[j-1]=atoi(t);
2036  j++; m=0;
2037  }
2038  else
2039  { t[m]=s[i]; m++; }
2040  break;
2041  default: //j=0, 3..6
2042  if (s[i] == ',')
2043  {
2044  // j=0: 126
2045  //(j=1..2: data in b[] )
2046  // j=3: planar
2047  // j=4: open/closed curve
2048  // j=5: rational
2049  // j=6: periodic
2050  // b[0]+b[1]+2 knots
2051  // b[0]+1 weights
2052  // control points
2053  t[m]= '\0';
2054  m= 0;
2055  //printf("%d: Got number: %s\n", j, t);
2056  j++;
2057  }
2058  else
2059  { /* digit + - E e D d */
2060  t[m]= s[i];
2061  m++;
2062  break;
2063  }
2064  if ( 7 == j )
2065  {
2066  endknot = b[0]+b[1]+2;
2067  phase=1; // knots start
2068  }
2069  }
2070  break;
2071  case 3: // PHASE CP
2072  if (s[i] == ' ') return;
2073  else if (s[i] == ',' || s[i] == ';') /* the last coordinate */
2074  {
2075  t[m]='\0';
2076  format_number(t);
2077  ss <<" "<< t;
2078  m= 0;
2079  c++;
2080  if (c == 3*(b[0]+1))
2081  {
2082  c=0;
2083  return;
2084  }
2085  }
2086  else
2087  { /* digit + - E e D d */
2088  t[m]= s[i];
2089  m++;
2090  }
2091  break;
2092  case 1: // PHASE knots
2093  if (s[i] == ' ') return;
2094  else if (s[i] == ',')
2095  { /* next knot */
2096  t[m]= '\0';
2097  format_number(t);
2098  ss <<" "<< t;
2099  m= 0;
2100  c++;
2101  }
2102  else { /* digit + - E e D d */
2103  t[m]= s[i];
2104  m++;
2105  break;
2106  }
2107 
2108  if (c == endknot)
2109  {
2110  ss<<","<<b[1]<<",";
2111  c=0;
2112  phase=2; //weights start
2113  }
2114  break;
2115  case 2: // PHASE weights
2116  if (s[i] == ' ') return;
2117  else if (s[i] == ',')
2118  { /* next knot */
2119  t[m]= '\0';
2120  format_number(t);
2121  ss <<" "<< t;
2122  m= 0;
2123  c++;
2124  }
2125  else { /* digit + - E e D d */
2126  t[m]= s[i];
2127  m++;
2128  break;
2129  }
2130 
2131  if (c == (b[0]+1))
2132  {
2133  ss<<",";
2134  c=0;
2135  phase=3; //control points start
2136  }
2137  break;
2138  }
2139  }
2140 }
2141 
2142 
2143 // todo: Write file
2144 
2145 
2146 }//namespace
2147 
2148 template<class T>
2149 bool gsFileData<T>::readIgesFile( String const & fn )
2150 {
2151  //Input file
2152  FILE * fr = fopen(fn.c_str(), "rb");
2153 
2154  int entity[MAXENTITY][4];
2155  int entity_sum=0, /* A number of entities in array entity[] */
2156  emark=0; /* for cycling over entity[] */
2157 
2158  if ( NULL==fr )
2159  {
2160  gsWarn<<"gsFileData: Problem with input "<<fn<<": Cannot open file.\n";
2161  return false;
2162  }
2163 
2164  char line[81], /* text content of current line from IGES */
2165  pairline[81]; /* pair line (in D section of IGES file) */
2166  char pd_seq_s[8]; pd_seq_s[7]='\0';
2167  int pd_seq; /* parameter data sequence number */
2168  int err_code;
2169 
2170  if (read_iges_line(fr, line) == -1)
2171  { gsWarn<<"IGES file empty.\n"; return false; }
2172  if (line[72] == 'F')
2173  { gsWarn<<"IGES file is not ASCII file (binary mode is not supported).\n"; return false; }
2174 
2175  /* Skip S and G sections and find the 1st line of the 1st D entry,
2176  * then load 2nd line of the first D entry as well (2).
2177  * Analyze the pair of lines and if the enity is recognized, load it
2178  * into array entity[][] (3).
2179  * */
2180  while (line[72] != 'D')
2181  {
2182  err_code=read_iges_line(fr, line);
2183  if (err_code == -1) { gsWarn<<"IGES file empty.\n"; return false; }
2184  }
2185  err_code=read_iges_line(fr, pairline); /* (2) */
2186  if (err_code == -1) { gsWarn<<"IGES file empty.\n"; return false; }
2187  parse_d_entry(entity,emark,entity_sum,line, pairline); /* (3) */
2188 
2189  /* Repeat the same on subsequent entries in D section */
2190  while (line[72] == 'D')
2191  {
2192  err_code=read_iges_line(fr, line);
2193  if (err_code == -1) { gsWarn<<"IGES file empty.\n"; return false; }
2194  if (line[72] == 'D')
2195  {
2196  err_code=read_iges_line(fr, pairline);
2197  if (err_code == -1) { gsWarn<<"IGES file empty.\n"; return false; }
2198  parse_d_entry(entity,emark,entity_sum,line, pairline);
2199  if (entity_sum >= MAXENTITY) { gsWarn<<"Too many entities (more than "<<MAXENTITY<<" in the file.\n"; return false; }
2200  }
2201  }
2202 
2203  /* For every entity in array entity[] find PD line with the sequence nr
2204  * and process subsequent lines (find coordinates and write to text file).
2205  * */
2206  copy_field(line,73,7,pd_seq_s);
2207  pd_seq = atoi(pd_seq_s);
2208  for (emark=0; emark < entity_sum; emark++)
2209  {
2210  while (pd_seq != entity[emark][PD_PTR]) /* find line in PD */
2211  {
2212  read_iges_line(fr, line);
2213  copy_field(line,73,7,pd_seq_s);
2214  pd_seq=atoi(pd_seq_s);
2215  }
2216 
2217  std::stringstream ss;
2218  std::string token;
2219 
2220  switch (entity[emark][E_TYPE])
2221  {
2222  /*
2223  case 406:
2224  for (i=1; i <= entity[emark][PD_CNT]; i++) {
2225  read_pd406(line, i);
2226  read_iges_line(fr, line);
2227  copy_field(line,73,7,pd_seq_s); pd_seq=atoi(pd_seq_s);
2228  }
2229  break;
2230  case 106:
2231  if (o_write_layername == 1) {
2232  fprintf(fw, "%s\n", layer[entity[emark][ELAYER]]);
2233  }
2234  fprintf(fw, "\n");
2235  for (i=1; i <= entity[emark][PD_CNT]; i++) {
2236  read_pd106_writetxt(line, i);
2237  read_iges_line(fr, line);
2238  copy_field(line,73,7,pd_seq_s); pd_seq=atoi(pd_seq_s);
2239  }
2240  fprintf(fw, "\n");
2241  break;
2242  case 116:
2243  for (i=1; i <= entity[emark][PD_CNT]; i++) {
2244  read_pd116_writetxt(line, i);
2245  read_iges_line(fr, line);
2246  copy_field(line,73,7,pd_seq_s); pd_seq=atoi(pd_seq_s);
2247  }
2248  break;
2249  */
2250  case 126:
2251  // layer name: layer[entity[emark][ELAYER]];
2252  for (int i=1; i <= entity[emark][PD_CNT]; i++)
2253  {
2254  read_iges_pd126(line, i, ss);
2255  read_iges_line(fr, line);
2256  copy_field(line,73,7,pd_seq_s);
2257  pd_seq=atoi(pd_seq_s);
2258  }
2259  break;
2260  case 128:
2261  for (int i=1; i <= entity[emark][PD_CNT]; i++)
2262  {
2263  read_iges_pd128(line, i, ss);
2264  read_iges_line(fr, line);
2265  copy_field(line,73,7,pd_seq_s);
2266  pd_seq=atoi(pd_seq_s);
2267  }
2268 
2269  //Debug
2270  //gsInfo<<"\nREAD\n"; while(std::getline(ss, token, ',')) gsInfo << token << '\n'; break;
2271 
2272  std::getline(ss, token, ',');
2273  bool rat = (token!="0");
2274  gsXmlNode* g = internal::makeNode("Geometry", *data);
2275  g->append_attribute( internal::makeAttribute("type",
2276  (rat?"TensorNurbs2":"TensorBSpline2"), *data) );
2277  data->appendToRoot(g);
2278  gsXmlNode* rtb(nullptr), * src;
2279  src = internal::makeNode("Basis", *data);
2280  if (rat)
2281  {
2282  rtb = internal::makeNode("Basis", *data);
2283  rtb->append_attribute( internal::makeAttribute("type", "TensorNurbsBasis2", *data) );
2284  g->append_node(rtb);
2285  rtb->append_node(src);
2286  }
2287  else
2288  g->append_node(src);
2289  src->append_attribute( internal::makeAttribute("type","TensorBSplineBasis2", *data) );
2290  gsXmlNode* b = internal::makeNode("Basis", *data);
2291  b->append_attribute( internal::makeAttribute("index", 0, *data) );
2292  b->append_attribute( internal::makeAttribute("type", "BSplineBasis", *data) );
2293  src->append_node(b);
2294  std::getline(ss, token, ',');
2295  gsXmlNode* k = internal::makeNode("KnotVector", token, *data);
2296  std::getline(ss, token, ',');
2297  k->append_attribute( internal::makeAttribute("degree", token, *data) ) ;
2298  b->append_node(k);
2299  b = internal::makeNode("Basis", *data);
2300  b->append_attribute( internal::makeAttribute("index", 1, *data) );
2301  b->append_attribute( internal::makeAttribute("type", "BSplineBasis", *data) );
2302  src->append_node(b);
2303  std::getline(ss, token, ',');
2304  k = internal::makeNode("KnotVector", token, *data);
2305  std::getline(ss, token, ',');
2306  k->append_attribute( internal::makeAttribute("degree", token, *data) ) ;
2307  b->append_node(k);
2308  std::getline(ss, token, ',');
2309  if (rat)
2310  {
2311  k = internal::makeNode("weights", token, *data);
2312  rtb->append_node(k);
2313  }
2314  std::getline(ss, token, ',');
2315  k = internal::makeNode("coefs", token, *data);
2316  k->append_attribute( internal::makeAttribute("geoDim", 3, *data ) );
2317  g->append_node(k);
2318  break;
2319  }
2320  }
2321 
2322  const bool fc = ( 0==fclose(fr) );
2323  if (fc) gsWarn<< "File closing didn't succeeded!\n";
2324  return fc;
2325 }
2326 
2327 #undef MAXENTITY
2328 #undef FIELD_L
2329 
2330 template<class T>
2331 void gsFileData<T>::addX3dShape(gsXmlNode * shape)
2332 {
2333  // assert shape->name()==Shape
2334 
2335  gsXmlNode * patch;
2336 
2337  //node = node->first_node("NurbsTrimmedSurface");
2338  //node = node->first_node("NurbsCurve2D");
2339  //node = node->first_node("NurbsCurve");
2340 
2341  int p;
2342  char * ch = 0;
2343  std::istringstream str;
2344 
2345  for (gsXmlNode * node = shape->first_node("NurbsPatchSurface");
2346  node; node = node->next_sibling("NurbsPatchSurface") )
2347  {
2348  // Read TensorBSplineBasis
2349  gsXmlNode* tp_node = internal::makeNode("Basis" , *data);
2350  tp_node->append_attribute( internal::makeAttribute("type",
2351  "TensorBSplineBasis2", *data) );
2352 
2353  // gsDebug<<"node "<< node <<"\n";
2354  // gsDebug<<"uOrder "<< node->first_attribute("uOrder") <<"\n";
2355  // gsDebug<<"uKnot "<< node->first_attribute("uKnot")<<"\n";
2356 
2357  p = atoi(node->first_attribute("uOrder")->value()) -1 ;
2358  gsXmlAttribute * kv_attr = node->first_attribute("uKnot");
2359 
2360  if ( kv_attr )
2361  ch = node->first_attribute("uKnot")->value() ;
2362  else
2363  {
2364  // make 0..1 knots by default
2365  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
2366  <<": Setting knots to [0..1] by default not implemented";
2367  }
2368  gsXmlNode * kv_node = internal::makeNode("KnotVector", String(ch), *data);
2369  kv_node->append_attribute( internal::makeAttribute("degree", p, *data) );
2370  gsXmlNode* bs_node = internal::makeNode("Basis" , *data);
2371  bs_node->append_attribute( internal::makeAttribute("type", "BSplineBasis", *data) );
2372  bs_node->append_attribute( internal::makeAttribute("index", 0, *data) );
2373  bs_node->append_node(kv_node);
2374  tp_node->append_node(bs_node);
2375 
2376  p = atoi(node->first_attribute("vOrder")->value()) -1 ;
2377  kv_attr = node->first_attribute("vKnot");
2378  if ( kv_attr )
2379  ch = kv_attr->value() ;
2380  else
2381  {
2382  // make 0..1 knots by default
2383  gsWarn<<"gsFileData: Problem with file "<<m_lastPath
2384  <<": Setting knots to [0..1] by default not implemented";
2385  }
2386  kv_node = internal::makeNode("KnotVector", String(ch), *data);
2387  kv_node->append_attribute( internal::makeAttribute("degree", p, *data) );
2388  bs_node = internal::makeNode("Basis" , *data);
2389  bs_node->append_attribute( internal::makeAttribute("type", "BSplineBasis", *data) );
2390  bs_node->append_attribute( internal::makeAttribute("index", 1, *data) );
2391  bs_node->append_node(kv_node);
2392  tp_node->append_node(bs_node);
2393 
2394  patch = internal::makeNode("Geometry" , *data);
2395  gsXmlAttribute * rat_weights = node->first_attribute("weight");
2396  if ( rat_weights )
2397  {
2398  // If nurbs, read weights etc
2399  ch = rat_weights->value();
2400  patch->append_attribute(internal::makeAttribute("type",
2401  "TensorNurbs2", *data));
2402 
2403  gsXmlNode* nurbs_node = internal::makeNode("Basis" , *data);
2404  nurbs_node->append_attribute( internal::makeAttribute("type",
2405  "TensorNurbsBasis2", *data) );
2406  nurbs_node->append_node(tp_node);
2407  gsXmlNode * weights_node = internal::makeNode("weights",String(ch), *data);
2408  nurbs_node->append_node(weights_node);
2409  patch->append_node(nurbs_node);
2410  }
2411  else
2412  {
2413  // Attach basis to the patch
2414  patch->append_attribute(internal::makeAttribute("type",
2415  "TensorBSpline2", *data));
2416  patch->append_node( tp_node);
2417  }
2418 
2419  // Attach the control points to the patch
2420  ch = node->first_node("Coordinate")->first_attribute("point")->value();
2421  gsXmlNode* cp_node = internal::makeNode("coefs",String(ch), *data);
2422  cp_node->append_attribute( internal::makeAttribute("geoDim", 3, *data) );
2423  patch->append_node( cp_node);
2424 
2425  // Attach patch to gismo xml tree
2426  data->appendToRoot(patch);
2427  }
2428 }
2429 
2430 template<class T>
2431 void gsFileData<T>::addX3dTransform(gsXmlNode * trans)
2432 {
2433 
2434  gsXmlAttribute * attr = trans->first_attribute("translation");
2435  if ( attr )
2436  gsDebug<<"Translate "<< attr->value() <<"\n";// (x,y,z)
2437 
2438 
2439  attr = trans->first_attribute("rotation");
2440  if ( attr )
2441  gsDebug<<"Rotate "<< attr->value() <<"\n";// (x,y,z,angle)
2442 
2443 
2444  attr = trans->first_attribute("scale");
2445  if ( attr )
2446  gsDebug<<"Scale "<< attr->value() <<"\n";// (x,y,z)
2447 
2448 //<transform dim="3">
2449 // all children optional
2450 //<translation>x,y,z</translation>
2451 //<rotation>x y z angle</rotation>
2452 //<scale>x y z</scale>
2453 //<Matrix>---</Matrix>
2454 //</transform>
2455 
2456 }
2457 
2458 
2459 template<class T>
2460 bool gsFileData<T>::readX3dFile( String const & fn )
2461 {
2462  // http://www.web3d.org/x3d/content/examples/NURBS/
2463  // Open file
2464  std::ifstream file(fn.c_str(), std::ios::in);
2465  if ( file.fail() )
2466  {gsWarn<<"gsFileData: Problem with file "<<fn<<": cannot open file stream.\n"; return false;}
2467 
2468  std::vector<char> buffer(
2469  std::istreambuf_iterator<char>(file.rdbuf() ),
2470  std::istreambuf_iterator<char>() );
2471  buffer.push_back('\0');
2472 
2473  // Read X3D data
2474  FileData x3ddata;
2475  x3ddata.parse<0>(&buffer[0]);
2476 
2477  // Look for the root <X3D>
2478  gsXmlNode * x3d = x3ddata.first_node("X3D");
2479 
2480  // Looking for shapes
2481  for (gsXmlNode * scene = x3d->first_node("Scene");
2482  scene; scene = scene->next_sibling("Scene") )
2483  {
2484  for (gsXmlNode * shape = scene->first_node("Shape");
2485  shape; shape = shape->next_sibling("Shape") )
2486  addX3dShape( shape );
2487 
2488  for (gsXmlNode * trans = scene->first_node("Transform");
2489  trans; trans = trans->next_sibling("Transform") )
2490  {
2491  // Descent to transforms
2492  gsXmlNode * trans_rec = trans;
2493  while ( true )
2494  {
2495  addX3dTransform( trans_rec );
2496  gsXmlNode * tmp = trans_rec->first_node("Transform");
2497  if ( tmp )
2498  trans_rec = tmp;
2499  else
2500  break;
2501  }
2502 
2503  for (gsXmlNode * shape = trans_rec->first_node("Shape");
2504  shape; shape = shape->next_sibling("Shape") )
2505  {
2506  addX3dShape( shape );
2507  }
2508 
2509  for (gsXmlNode * coll = trans->first_node("Collision");
2510  coll; coll = trans->next_sibling("Collision") )
2511  {
2512  gsDebug<<"Reach collision tag.\n";
2513  for (gsXmlNode * shape = coll->first_node("Shape");
2514  shape; shape = shape->next_sibling("Shape") )
2515  {
2516  gsDebug<<"Reach shape in tag.\n";
2517  addX3dShape( shape );
2518  }
2519  }
2520  }
2521  }
2522 
2523  return true;
2524 }
2525 
2526 template<class T>
2527 bool gsFileData<T>::read3dmFile( String const & fn )
2528 {
2529 #ifdef gsOpennurbs_ENABLED
2530  return extensions::gsReadOpenNurbs( fn.c_str(), *data);
2531 #else
2532  GISMO_UNUSED(fn);
2533  return false;
2534 #endif
2535 }
2536 
2537 
2538 template<class T>
2539 bool gsFileData<T>::readParasolidFile( String const & fn )
2540 {
2541  // Remove extension and pass to parasolid
2542  //int lastindex = fn.find_last_of(".");
2543  //return extensions::gsReadParasolid( fn.substr(0, lastindex).c_str(), *data);
2544 #ifdef GISMO_WITH_PSOLID
2545  return extensions::gsReadParasolid( fn.c_str(), *data);
2546 #else
2547  GISMO_UNUSED(fn);
2548  return false;
2549 #endif
2550 }
2551 
2552 template<class T>
2553 bool gsFileData<T>::readCsvFile( String const & fn )
2554 {
2555  std::ifstream indata;
2556  indata.open(fn.c_str());
2557  std::string cell, line, mstr;
2558  index_t rows = 0, nv = 0;
2559  std::istringstream lnstream;
2560  lnstream.unsetf(std::ios_base::skipws);
2561  while (std::getline(indata, line))
2562  {
2563  lnstream.clear();
2564  lnstream.str(line);
2565  while (std::getline(lnstream, cell, ','))
2566  {
2567  ++nv;
2568  mstr += cell + " ";
2569  }
2570  ++rows;
2571  }
2572  gsXmlNode * nd = internal::makeNode("Matrix", mstr, *data);
2573  nd->append_attribute( internal::makeAttribute("format","ascii",*data) );
2574  nd->append_attribute( internal::makeAttribute("rows",rows,*data) );
2575  nd->append_attribute( internal::makeAttribute("cols",nv/rows,*data) );
2576 
2577  data->appendToRoot(nd);
2578  return true;
2579 }
2580 
2581 template<class T>
2582 std::string
2584 {
2585  std::ostringstream os;
2586  os << "--- \n";
2587  int i(1);
2588  for (gsXmlNode * child = data->first_node("xml")->first_node();
2589  child; child = child->next_sibling() )
2590  {
2591  os << i++ <<". " << child->name() ;
2592  for (gsXmlAttribute * attr = child->first_attribute();
2593  attr; attr = attr->next_attribute() )
2594  os << ", "<< attr->name() << "="<< attr->value();
2595  os <<"\n";
2596  }
2597  os << "--- \n";
2598  return os.str();
2599 };
2600 
2601 template<class T> inline
2603 {
2604  int i(0);
2605  for (gsXmlNode * child = data->first_node("xml")->first_node() ;
2606  child; child = child->next_sibling() )
2607  ++i;
2608  return i;
2609 }
2610 
2611 template<class T> inline
2612 typename gsFileData<T>::gsXmlNode *
2614 {
2615  return data->getRoot();
2616 }
2617 
2618 template<class T> inline
2619 void gsFileData<T>::deleteXmlSubtree(gsXmlNode * node)
2620 {
2621  node->parent()->remove_node(node);
2622  // TO do: delete recursively ?
2623  delete node;
2624 }
2625 
2626 template<class T> inline
2627 typename gsFileData<T>::gsXmlNode *
2628 gsFileData<T>::getFirstNode(const std::string & name, const std::string & type) const
2629 {
2630  gsXmlNode * root = data->first_node("xml");
2631  if ( ! root )
2632  {
2633  gsWarn<< "gsFileData: Problem with file "<<m_lastPath
2634  <<": Invalid XML file, no root tag <xml> found.\n";
2635  assert( root ) ;
2636  }
2637 
2638  if ( type == "" )
2639  return root->first_node( name.c_str() );
2640  else
2641  {
2642  for (gsXmlNode * child = root->first_node( name.c_str() ) ;
2643  child; child = child->next_sibling( name.c_str() ) )
2644  if ( !strcmp( child->first_attribute("type")->value(), type.c_str() ) )
2645  return child;
2646  return NULL;
2647  }
2648 }
2649 
2650 template<class T> inline
2651 typename gsFileData<T>::gsXmlNode *
2652 gsFileData<T>::getAnyFirstNode(const std::string & name, const std::string & type) const
2653 {
2654  gsXmlNode * root = data->first_node("xml");
2655  assert( root ) ;
2656  if ( type == "" )
2657  // Searching up to third level of the XML tree
2658  for (gsXmlNode * child = root->first_node() ;
2659  child; child = child->next_sibling() )
2660  {
2661  if (!strcmp( child->name(), name.c_str() ) )
2662  return child;
2663  // Level 2
2664  for (gsXmlNode * child2 = child->first_node() ;
2665  child2; child2 = child2->next_sibling() )
2666  {
2667  if ( !strcmp( child2->name(), name.c_str() ) )
2668  return child2;
2669  // Level 3
2670  for (gsXmlNode * child3 = child2->first_node() ;
2671  child3; child3 = child3->next_sibling() )
2672  if ( !strcmp( child3->name(), name.c_str() ) )
2673  return child3;
2674  }
2675  }
2676  else
2677  // Searching up to third level of the XML tree
2678  for (gsXmlNode * child = root->first_node() ;
2679  child; child = child->next_sibling() )
2680  {
2681  if (!strcmp( child->name(), name.c_str() ) &&
2682  !strcmp( child->first_attribute("type")->value(), type.c_str() ) )
2683  return child;
2684  // Level 2
2685  for (gsXmlNode * child2 = child->first_node() ;
2686  child2; child2 = child2->next_sibling() )
2687  {
2688  if ( !strcmp( child2->name(), name.c_str() ) &&
2689  !strcmp( child2->first_attribute("type")->value(), type.c_str() ))
2690  return child2;
2691  // Level 3
2692  for (gsXmlNode * child3 = child2->first_node() ;
2693  child3; child3 = child3->next_sibling() )
2694  if ( !strcmp( child3->name(), name.c_str() ) &&
2695  !strcmp( child3->first_attribute("type")->value(), type.c_str()))
2696  return child3;
2697  }
2698  }
2699  return NULL;
2700 }
2701 
2702 template<class T> inline
2703 typename gsFileData<T>::gsXmlNode *
2704 gsFileData<T>::getNextSibling(gsXmlNode* const & node, const std::string & name,
2705  const std::string & type)
2706 {
2707  if ( type == "" )
2708  return node->next_sibling( name.c_str() );
2709  else
2710  {
2711  for (gsXmlNode * next = node->next_sibling( name.c_str() );
2712  next; next = next->next_sibling( name.c_str() ) )
2713  if ( !strcmp( next->first_attribute("type")->value(), type.c_str() ) )
2714  return next;
2715  return NULL;
2716  }
2717 }
2718 
2719 
2720 };// namespace gismo
Knot vector for B-splines.
bool readStlFile(String const &fn)
Reads STL mesh file.
Definition: gsFileData.hpp:1327
static std::string find(std::string fn)
Find a file.
Definition: gsFileManager.cpp:283
#define gsDebug
Definition: gsDebug.h:61
bool readParasolidFile(String const &fn)
Reads parasolid files.
Definition: gsFileData.hpp:2539
void saveCompressed(String const &fname="dump") const
Save file contents to compressed xml file.
Definition: gsFileData.hpp:131
static std::string getExtension(std::string const &fn)
Returns the extension of the filename fn.
Definition: gsFileManager.cpp:568
#define index_t
Definition: gsConfig.h:32
#define GISMO_ENSURE(cond, message)
Definition: gsDebug.h:102
Provides declaration of gsReadParasolid functions.
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
int numTags() const
Counts the number of Objects/tags in the filedata.
Definition: gsFileData.hpp:2602
bool readXmlGzFile(String const &fn, bool recursive=false)
Reads a file with xml.gz extension.
Definition: gsFileData.hpp:240
gsXmlNode * searchNode(gsXmlNode *root, const std::string &attr_name, const std::string &value, const char *tag_name=NULL)
Definition: gsXml.h:231
bool readOffFile(String const &fn)
Reads Off mesh file.
Definition: gsFileData.hpp:1259
std::string to_string(const unsigned &i)
Helper to convert small unsigned to string.
Definition: gsXml.cpp:74
bool readGismoXmlStream(std::istream &is, bool recursive=false)
Reads Gismo&#39;s native XML file.
Definition: gsFileData.hpp:252
#define gsWarn
Definition: gsDebug.h:50
gsXmlNode * makeComment(const std::string &comment, gsXmlTree &data)
Helper to create an XML comment node.
Definition: gsXml.cpp:68
EIGEN_STRONG_INLINE onormal_expr< T > nv(const gsGeometryMap< T > &u)
The (outer pointing) boundary normal of a geometry map.
Definition: gsExpressions.h:4508
String contents() const
Lists the contents of the filedata.
Definition: gsFileData.hpp:2583
bool readObjFile(String const &fn)
Reads Wavefront OBJ file.
Definition: gsFileData.hpp:1410
bool read(String const &fn, bool recursive=false)
Definition: gsFileData.hpp:162
void addInclude(const std::string &filename, const real_t &time=-1., const index_t &id=-1, const std::string &label="")
Add a reference ( &lt;xmlfile&gt; tag ) to another Gismo .xml file to the xml tree.
Definition: gsFileData.hpp:296
gsXmlAttribute * makeAttribute(const std::string &name, const std::string &value, gsXmlTree &data)
Helper to allocate XML attribute.
Definition: gsXml.cpp:37
bool readIgesFile(String const &fn)
Reads Iges file.
Definition: gsFileData.hpp:2149
#define GISMO_VERSION
Definition: gsConfig.h:20
Declaration of function for data input from the Rhinoceros 3DM file format.
bool readAxelFile(String const &fn)
Reads Axel file.
Definition: gsFileData.hpp:349
gsXmlNode * makeNode(const std::string &name, gsXmlTree &data)
Helper to allocate XML node.
Definition: gsXml.cpp:54
void dump(String const &fname="dump") const
Dump file contents to an xml file.
Definition: gsFileData.hpp:86
static std::string getPath(std::string const &fn, bool resolve=false)
Definition: gsFileManager.cpp:608
char * makeValue(const std::string &value, gsXmlTree &data)
Helper to allocate XML value.
Definition: gsXml.cpp:32
bool readGeompFile(String const &fn)
Reads GeoPDEs txt file.
Definition: gsFileData.hpp:882
void clear()
Clear all data.
Definition: gsFileData.hpp:69
bool read3dmFile(String const &fn)
Reads 3DM file.
Definition: gsFileData.hpp:2527
bool readX3dFile(String const &fn)
Reads X3D file.
Definition: gsFileData.hpp:2460
#define GISMO_UNUSED(x)
Definition: gsDebug.h:112
Utility class for finding files and handling paths.
#define GISMO_ERROR(message)
Definition: gsDebug.h:118
Reading OpenCascade .brep and others via OCCT.
bool readGoToolsFile(String const &fn)
Reads GoTools file.
Definition: gsFileData.hpp:511
This class represents an XML data tree which can be read from or written to a (file) stream...
Definition: gsFileData.h:33
bool ends_with(const std::string &haystack, const std::string &needle)
Checks if a string haystack ends with the string needle.
Definition: gsUtils.h:79
void save(String const &fname="dump", bool compress=false) const
Save file contents to an xml file.
Definition: gsFileData.hpp:98
bool readBrepFile(String const &fn)
Reads OpenCascade brep file.
Definition: gsFileData.hpp:1694
bool readXmlFile(String const &fn, bool recursive=false)
Reads a file with xml extension.
Definition: gsFileData.hpp:229
std::ostream & print(std::ostream &os) const
Prints the XML data as a string.
Definition: gsFileData.hpp:77
static std::string getSearchPaths()
Get the defined search paths.
Definition: gsFileManager.cpp:271