G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
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
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
43namespace gismo {
44
45template<class T>
46gsFileData<T>::gsFileData()
47{
48 data = new FileData;
49 data->makeRoot();
50}
51
52template<class T>
53gsFileData<T>::gsFileData(String const & fn, bool recursive)
54{
55 data = new FileData;
56 data->makeRoot();
57 this->read(fn, recursive);
58}
59
60template<class T>
62{
63 data->clear();
64 delete data;
65}
66
67
68template<class T> void
70{
71 data->clear();
72 data->makeRoot(); // ready to re-use
73}
75
76template<class T>
77std::ostream & gsFileData<T>::print(std::ostream &os) const
78{
79 //rapidxml::print_no_indenting
80 os<< *data;
81 return os;
82}
84
85template<class T> void
86gsFileData<T>::dump(std::string const & fname) const
87{ save(fname); }
88
89
90template<class T> void
91gsFileData<T>::addComment(std::string const & message)
92{
93 gsXmlNode * comment = internal::makeComment(message, *data);
94 data->appendToRoot(comment);
95}
96
97template<class T> void
98gsFileData<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;
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}
130template<class T> void
131gsFileData<T>::saveCompressed(std::string const & fname) const
132{
133 String tmp = gsFileManager::getExtension(fname);
134 if (tmp != "gz" )
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
153template<class T> void
154gsFileData<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");
160
161template<class T>
162bool 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
228template<class T>
229bool 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
239template<class T>
240bool 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
251template<class T>
252bool 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
295template<class T>
296void 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
307template<class T>
308void 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 }
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
348template<class T>
349bool 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
386template<class T>
387bool 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);
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
424template<class T>
425bool 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
476template<class T>
477bool 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
510template<class T>
511bool 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
881template<class T>
882bool 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
1258template<class T>
1259bool 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
1326template<class T>
1327bool 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
1409template<class T>
1410bool 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
1693template<class T>
1694bool 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
1704namespace
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
1710enum entity_j_name{
1711 E_TYPE= 0,
1712 PD_PTR= 1,
1713 PD_CNT= 2,
1714 ELAYER= 3
1715};
1716
1717int 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
1739void 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
1751void 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
1789void 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
1859void 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
2006void 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
2148template<class T>
2149bool 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
2330template<class T>
2331void 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
2430template<class T>
2431void 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
2459template<class T>
2460bool 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
2526template<class T>
2527bool 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
2538template<class T>
2539bool 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
2552template<class T>
2553bool 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
2581template<class T>
2582std::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
2601template<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
2611template<class T> inline
2612typename gsFileData<T>::gsXmlNode *
2614{
2615 return data->getRoot();
2616}
2617
2618template<class T> inline
2619void gsFileData<T>::deleteXmlSubtree(gsXmlNode * node)
2620{
2621 node->parent()->remove_node(node);
2622 // TO do: delete recursively ?
2623 delete node;
2624}
2625
2626template<class T> inline
2627typename gsFileData<T>::gsXmlNode *
2628gsFileData<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
2650template<class T> inline
2651typename gsFileData<T>::gsXmlNode *
2652gsFileData<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
2702template<class T> inline
2703typename gsFileData<T>::gsXmlNode *
2704gsFileData<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
This class represents an XML data tree which can be read from or written to a (file) stream.
Definition gsFileData.h:34
void addInclude(const std::string &filename, const real_t &time=-1., const index_t &id=-1, const std::string &label="")
Add a reference ( <xmlfile> tag ) to another Gismo .xml file to the xml tree.
Definition gsFileData.hpp:296
bool readObjFile(String const &fn)
Reads Wavefront OBJ file.
Definition gsFileData.hpp:1410
bool readIgesFile(String const &fn)
Reads Iges file.
Definition gsFileData.hpp:2149
bool readBrepFile(String const &fn)
Reads OpenCascade brep file.
Definition gsFileData.hpp:1694
void saveCompressed(String const &fname="dump") const
Save file contents to compressed xml file.
Definition gsFileData.hpp:131
bool readGoToolsFile(String const &fn)
Reads GoTools file.
Definition gsFileData.hpp:511
bool readStlFile(String const &fn)
Reads STL mesh file.
Definition gsFileData.hpp:1327
bool readXmlFile(String const &fn, bool recursive=false)
Reads a file with xml extension.
Definition gsFileData.hpp:229
int numTags() const
Counts the number of Objects/tags in the filedata.
Definition gsFileData.hpp:2602
bool read3dmFile(String const &fn)
Reads 3DM file.
Definition gsFileData.hpp:2527
String contents() const
Lists the contents of the filedata.
Definition gsFileData.hpp:2583
bool readGeompFile(String const &fn)
Reads GeoPDEs txt file.
Definition gsFileData.hpp:882
void save(String const &fname="dump", bool compress=false) const
Save file contents to an xml file.
Definition gsFileData.hpp:98
bool readGismoXmlStream(std::istream &is, bool recursive=false)
Reads Gismo's native XML file.
Definition gsFileData.hpp:252
bool readX3dFile(String const &fn)
Reads X3D file.
Definition gsFileData.hpp:2460
void clear()
Clear all data.
Definition gsFileData.hpp:69
bool readXmlGzFile(String const &fn, bool recursive=false)
Reads a file with xml.gz extension.
Definition gsFileData.hpp:240
bool read(String const &fn, bool recursive=false)
Definition gsFileData.hpp:162
bool readOffFile(String const &fn)
Reads Off mesh file.
Definition gsFileData.hpp:1259
std::ostream & print(std::ostream &os) const
Prints the XML data as a string.
Definition gsFileData.hpp:77
bool readAxelFile(String const &fn)
Reads Axel file.
Definition gsFileData.hpp:349
bool readParasolidFile(String const &fn)
Reads parasolid files.
Definition gsFileData.hpp:2539
void dump(String const &fname="dump") const
Dump file contents to an xml file.
Definition gsFileData.hpp:86
static std::string getExtension(std::string const &fn)
Returns the extension of the filename fn.
Definition gsFileManager.cpp:568
static std::string getPath(std::string const &fn, bool resolve=false)
Definition gsFileManager.cpp:608
static std::string getSearchPaths()
Get the defined search paths.
Definition gsFileManager.cpp:271
static std::string find(std::string fn)
Find a file.
Definition gsFileManager.cpp:283
A matrix with arbitrary coefficient type and fixed or dynamic size.
Definition gsMatrix.h:41
A vector with arbitrary coefficient type and fixed or dynamic size.
Definition gsVector.h:37
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
#define index_t
Definition gsConfig.h:32
#define GISMO_VERSION
Definition gsConfig.h:20
#define gsDebug
Definition gsDebug.h:61
#define GISMO_ERROR(message)
Definition gsDebug.h:118
#define gsWarn
Definition gsDebug.h:50
#define GISMO_UNUSED(x)
Definition gsDebug.h:112
#define GISMO_ENSURE(cond, message)
Definition gsDebug.h:102
#define GISMO_ASSERT(cond, message)
Definition gsDebug.h:89
Utility class for finding files and handling paths.
Knot vector for B-splines.
Reading OpenCascade .brep and others via OCCT.
Declaration of function for data input from the Rhinoceros 3DM file format.
Provides declaration of gsReadParasolid functions.
gsXmlNode * makeComment(const std::string &comment, gsXmlTree &data)
Helper to create an XML comment node.
Definition gsXml.cpp:68
char * makeValue(const std::string &value, gsXmlTree &data)
Helper to allocate XML value.
Definition gsXml.cpp:32
std::string to_string(const unsigned &i)
Helper to convert small unsigned to string.
Definition gsXml.cpp:74
gsXmlNode * searchNode(gsXmlNode *root, const std::string &attr_name, const std::string &value, const char *tag_name=NULL)
Definition gsXml.h:231
gsXmlNode * makeNode(const std::string &name, gsXmlTree &data)
Helper to allocate XML node.
Definition gsXml.cpp:54
gsXmlAttribute * makeAttribute(const std::string &name, const std::string &value, gsXmlTree &data)
Helper to allocate XML attribute.
Definition gsXml.cpp:37
The G+Smo namespace, containing all definitions for the library.