OGS
FileIO::Gocad::GocadAsciiReader Namespace Reference

Enumerations

enum class  NodeType { UNSPECIFIED , VRTX , PVRTX }
 

Functions

void checkMeshNames (std::vector< std::unique_ptr< MeshLib::Mesh > > const &meshes)
 
bool isCommentLine (std::string const &str)
 Checks if the current line is a comment. More...
 
bool skipToEND (std::ifstream &in)
 Parses current section until END-tag is reached. More...
 
bool isKeyword (DataType const t, std::string const &line)
 Checks if current line is a designated keyword for a GoCAD data set. More...
 
DataType datasetFound (std::ifstream &in)
 Checks if a GoCAD data set begins at the current stream position. More...
 
void checkLineEndings (std::string const &file_name)
 Checks if current line is a designated keyword for a GoCAD data set. More...
 
bool parseHeader (std::ifstream &in, std::string &mesh_name)
 Parses the HEADER section (everything except the name is ignored right now) More...
 
bool parsePropertyClass (std::ifstream &in)
 
std::string propertyCheck (std::string const &string)
 Checks if the current line starts with one of the allowed keywords. More...
 
bool parseProperties (std::ifstream &in, std::vector< std::string > const &names, MeshLib::Properties &mesh_prop)
 
MeshLib::NodecreateNode (std::stringstream &sstr)
 
bool parseAtomRegionIndicators (std::ifstream &in)
 
bool parseNodes (std::ifstream &in, std::vector< MeshLib::Node * > &nodes, std::map< std::size_t, std::size_t > &node_id_map, MeshLib::Properties const &mesh_prop)
 Parses the node data for the current mesh. More...
 
bool parseLineSegments (std::ifstream &in, std::vector< MeshLib::Node * > &nodes, std::vector< MeshLib::Element * > &elems, std::map< std::size_t, std::size_t > const &node_id_map, MeshLib::Properties &mesh_prop)
 Parses the segments of the current line. More...
 
bool parseLine (std::ifstream &in, std::vector< MeshLib::Node * > &nodes, std::vector< MeshLib::Element * > &elems, std::map< std::size_t, std::size_t > &node_id_map, MeshLib::Properties &mesh_prop)
 Parses line information (nodes, segments, properties) More...
 
bool parseElements (std::ifstream &in, std::vector< MeshLib::Node * > &nodes, std::vector< MeshLib::Element * > &elems, std::map< std::size_t, std::size_t > const &node_id_map, MeshLib::Properties &mesh_prop)
 Parses the element data for the current mesh. More...
 
bool parseSurface (std::ifstream &in, std::vector< MeshLib::Node * > &nodes, std::vector< MeshLib::Element * > &elems, std::map< std::size_t, std::size_t > &node_id_map, MeshLib::Properties &mesh_prop)
 Parses the surface information (nodes, triangles, properties) More...
 
template<typename T >
MeshLib::MeshcreateMesh (std::ifstream &in, DataType type, std::string &mesh_name, MeshLib::Properties &mesh_prop, T parser, bool const flip_elevation)
 Converts parsed data into mesh. More...
 
MeshLib::MeshreadData (std::ifstream &in, DataType const &type, std::string &mesh_name)
 Reads one mesh contained in the file (there may be more than one!) More...
 
bool readFile (std::string const &file_name, std::vector< std::unique_ptr< MeshLib::Mesh > > &meshes, DataType const export_type=DataType::ALL)
 Reads the specified file and writes data into internal mesh vector. More...
 

Variables

const std::string mat_id_name = "MaterialIDs"
 
const std::string eof_error = "Error: Unexpected end of file."
 

Enumeration Type Documentation

◆ NodeType

Function Documentation

◆ checkLineEndings()

void FileIO::Gocad::GocadAsciiReader::checkLineEndings ( std::string const &  file_name)

Checks if current line is a designated keyword for a GoCAD data set.

Definition at line 122 of file GocadAsciiReader.cpp.

123{
124#ifndef _WIN32
125 std::ifstream in(file_name);
126 if (in.is_open())
127 {
128 std::string line;
129 std::getline(in, line);
130 if (line.back() == '\r')
131 {
132 OGS_FATAL(
133 "Error in input file: {:s}. The line endings are in windows "
134 "format. To read this file under UNIX, transform the input "
135 "file to unix style line endings (e.g. dos2unix).",
136 file_name);
137 }
138 }
139#endif
140}
#define OGS_FATAL(...)
Definition: Error.h:26

References OGS_FATAL.

Referenced by readFile().

◆ checkMeshNames()

void FileIO::Gocad::GocadAsciiReader::checkMeshNames ( std::vector< std::unique_ptr< MeshLib::Mesh > > const &  meshes)

A GoCAD file may contain multiple datasets with the same name. To avoid conflicts when writing meshes, a unique id is appended to the mesh name if another dataset with the same name exists.

Definition at line 43 of file GocadAsciiReader.cpp.

44{
45 std::size_t const n_meshes = meshes.size();
46 for (std::size_t i = 0; i < n_meshes; ++i)
47 {
48 std::string const& name = meshes[i]->getName();
49 for (std::size_t j = i + 1; j < n_meshes; ++j)
50 {
51 if (meshes[j]->getName() == name)
52 {
53 std::string const id_str = std::to_string(meshes[j]->getID());
54 meshes[i]->setName(name + "--importID-" + id_str);
55 break;
56 }
57 }
58 }
59}
std::string getName(std::string const &line)
Returns the name/title from the "Zone"-description.

References getName(), and MaterialPropertyLib::name.

Referenced by readFile().

◆ createMesh()

template<typename T >
MeshLib::Mesh * FileIO::Gocad::GocadAsciiReader::createMesh ( std::ifstream &  in,
DataType  type,
std::string &  mesh_name,
MeshLib::Properties mesh_prop,
parser,
bool const  flip_elevation 
)

Converts parsed data into mesh.

Definition at line 553 of file GocadAsciiReader.cpp.

557{
558 std::vector<MeshLib::Node*> nodes;
559 std::vector<MeshLib::Element*> elems;
560 std::map<std::size_t, std::size_t> node_id_map;
561 INFO("Parsing {:s} {:s}.", dataType2ShortString(type), mesh_name);
562 bool return_val;
563 return_val = parser(in, nodes, elems, node_id_map, mesh_prop);
564
565 if (return_val)
566 {
567 if (flip_elevation)
568 {
569 std::for_each(nodes.begin(), nodes.end(),
570 [](MeshLib::Node* n) { (*n)[2] *= -1; });
571 }
572 return new MeshLib::Mesh(mesh_name, nodes, elems, mesh_prop);
573 }
574 ERR("Error parsing {:s} {:s}.", dataType2ShortString(type), mesh_name);
575 BaseLib::cleanupVectorElements(nodes, elems);
576 return nullptr;
577}
void INFO(char const *fmt, Args const &... args)
Definition: Logging.h:34
void ERR(char const *fmt, Args const &... args)
Definition: Logging.h:44
void cleanupVectorElements(std::vector< T * > &items)
Definition: Algorithm.h:300
std::string dataType2ShortString(DataType const t)
Given a Gocad DataType this returns the appropriate short form.
Definition: GocadEnums.cpp:41

References BaseLib::cleanupVectorElements(), FileIO::Gocad::dataType2ShortString(), ERR(), and INFO().

Referenced by readData().

◆ createNode()

MeshLib::Node * FileIO::Gocad::GocadAsciiReader::createNode ( std::stringstream &  sstr)

Definition at line 252 of file GocadAsciiReader.cpp.

253{
254 std::string keyword;
255 std::size_t id;
256 std::array<double, 3> data{};
257 sstr >> keyword >> id >> data[0] >> data[1] >> data[2];
258 return new MeshLib::Node(data, id);
259}

Referenced by parseNodes().

◆ datasetFound()

DataType FileIO::Gocad::GocadAsciiReader::datasetFound ( std::ifstream &  in)

Checks if a GoCAD data set begins at the current stream position.

Definition at line 90 of file GocadAsciiReader.cpp.

91{
92 std::string line;
93 while (std::getline(in, line))
94 {
95 if (line.empty() || isCommentLine(line))
96 {
97 continue;
98 }
99
100 if (isKeyword(DataType::VSET, line))
101 {
102 return DataType::VSET;
103 }
104 if (isKeyword(DataType::PLINE, line))
105 {
106 return DataType::PLINE;
107 }
108 if (isKeyword(DataType::TSURF, line))
109 {
110 return DataType::TSURF;
111 }
112 if (isKeyword(DataType::MODEL3D, line))
113 {
114 return DataType::MODEL3D;
115 }
116 ERR("No known identifier found...");
117 return DataType::UNDEFINED;
118 }
119 return DataType::UNDEFINED;
120}
bool isCommentLine(std::string const &str)
Checks if the current line is a comment.
bool isKeyword(DataType const t, std::string const &line)
Checks if current line is a designated keyword for a GoCAD data set.

References ERR(), isCommentLine(), isKeyword(), FileIO::Gocad::MODEL3D, FileIO::Gocad::PLINE, FileIO::Gocad::TSURF, FileIO::Gocad::UNDEFINED, and FileIO::Gocad::VSET.

Referenced by readFile().

◆ isCommentLine()

bool FileIO::Gocad::GocadAsciiReader::isCommentLine ( std::string const &  str)

Checks if the current line is a comment.

Definition at line 62 of file GocadAsciiReader.cpp.

63{
64 return (str.substr(0, 1) == "#");
65}

Referenced by datasetFound(), parseElements(), parseLineSegments(), parseNodes(), and readData().

◆ isKeyword()

bool FileIO::Gocad::GocadAsciiReader::isKeyword ( DataType const  t,
std::string const &  line 
)

Checks if current line is a designated keyword for a GoCAD data set.

Definition at line 83 of file GocadAsciiReader.cpp.

84{
85 std::size_t str_length = dataType2String(t).length();
86 return (line.substr(0, str_length) == dataType2String(t));
87}
std::string dataType2String(DataType const t)
Given a Gocad DataType this returns the appropriate string.
Definition: GocadEnums.cpp:16
static const double t

References FileIO::Gocad::dataType2String(), and MathLib::t.

Referenced by datasetFound().

◆ parseAtomRegionIndicators()

bool FileIO::Gocad::GocadAsciiReader::parseAtomRegionIndicators ( std::ifstream &  in)

parse Atom Region Indicator section for current TFACE (currently the information in this section is ignored)

Definition at line 263 of file GocadAsciiReader.cpp.

264{
265 std::string line;
266 while (std::getline(in, line))
267 {
268 if (line.substr(0, 26) == "END_ATOM_REGION_INDICATORS")
269 {
270 return true;
271 }
272 }
273 return false;
274}

Referenced by parseNodes().

◆ parseElements()

bool FileIO::Gocad::GocadAsciiReader::parseElements ( std::ifstream &  in,
std::vector< MeshLib::Node * > &  nodes,
std::vector< MeshLib::Element * > &  elems,
std::map< std::size_t, std::size_t > const &  node_id_map,
MeshLib::Properties mesh_prop 
)

Parses the element data for the current mesh.

Definition at line 448 of file GocadAsciiReader.cpp.

453{
455 *mesh_prop.getPropertyVector<int>(mat_id_name);
456 int current_mat_id(0);
457 if (!mat_ids.empty())
458 {
459 current_mat_id = (*std::max_element(mat_ids.begin(), mat_ids.end()))++;
460 }
461 std::streampos pos = in.tellg();
462 std::size_t id(0);
463 std::string line;
464 while (std::getline(in, line))
465 {
466 if (line.empty() || isCommentLine(line))
467 {
468 continue;
469 }
470 if (line.substr(0, 4) == "TRGL")
471 {
472 std::stringstream sstr(line);
473 std::string keyword;
474 std::array<std::size_t, 3> data{};
475 sstr >> keyword >> data[0] >> data[1] >> data[2];
476 std::array<MeshLib::Node*, 3> elem_nodes{};
477 for (std::size_t i = 0; i < 3; ++i)
478 {
479 auto const it = node_id_map.find(data[i]);
480 if (it == node_id_map.end() || it->second >= nodes.size())
481 {
482 ERR("Error: Node ID ({:d}) out of range (0, {:d}).",
483 data[i], nodes.back()->getID());
484 return false;
485 }
486 elem_nodes[i] = nodes[it->second];
487 }
488 elems.push_back(new MeshLib::Tri(elem_nodes, id++));
489 mat_ids.push_back(current_mat_id);
490 }
491 else
492 {
493 in.seekg(pos);
494 return true;
495 }
496 pos = in.tellg();
497 }
498 ERR("{:s}", eof_error);
499 return false;
500}
PropertyVector< T > const * getPropertyVector(std::string const &name) const

References eof_error, ERR(), MeshLib::Properties::getPropertyVector(), isCommentLine(), and mat_id_name.

Referenced by parseSurface().

◆ parseHeader()

bool FileIO::Gocad::GocadAsciiReader::parseHeader ( std::ifstream &  in,
std::string &  mesh_name 
)

Parses the HEADER section (everything except the name is ignored right now)

Definition at line 143 of file GocadAsciiReader.cpp.

144{
145 std::string line;
146 while (std::getline(in, line))
147 {
148 if (line.substr(0, 5) == "name:")
149 {
150 mesh_name = line.substr(5, line.length() - 5);
151 BaseLib::trim(mesh_name, ' ');
152 // replace chars that will prevent writing the file
153 std::replace(mesh_name.begin(), mesh_name.end(), '/', '-');
154 std::replace(mesh_name.begin(), mesh_name.end(), '\\', '-');
155 }
156 else if (line.substr(0, 1) == "}")
157 {
158 return true;
159 }
160 // ignore all other header parameters
161 }
162 ERR("{:s}", eof_error);
163 return false;
164}
void trim(std::string &str, char ch)
Definition: StringTools.cpp:58

References eof_error, ERR(), and BaseLib::trim().

Referenced by readData().

◆ parseLine()

bool FileIO::Gocad::GocadAsciiReader::parseLine ( std::ifstream &  in,
std::vector< MeshLib::Node * > &  nodes,
std::vector< MeshLib::Element * > &  elems,
std::map< std::size_t, std::size_t > &  node_id_map,
MeshLib::Properties mesh_prop 
)

Parses line information (nodes, segments, properties)

Definition at line 412 of file GocadAsciiReader.cpp.

417{
418 if (!parseNodes(in, nodes, node_id_map, mesh_prop))
419 {
420 return false;
421 }
422 if (!parseLineSegments(in, nodes, elems, node_id_map, mesh_prop))
423 {
424 return false;
425 }
426
427 std::string line;
428 while (std::getline(in, line))
429 {
430 std::vector<std::string> str = BaseLib::splitString(line);
431 if (str[0] == "ILINE")
432 {
433 parseLine(in, nodes, elems, node_id_map, mesh_prop);
434 return true;
435 }
436 if (line == "END")
437 {
438 return true;
439 }
440 WARN("GocadAsciiReader::parseLine() - Unknown keyword found: {:s}",
441 line);
442 }
443 ERR("{:s}", eof_error);
444 return false;
445}
void WARN(char const *fmt, Args const &... args)
Definition: Logging.h:39
std::vector< std::string > splitString(std::string const &str)
Definition: StringTools.cpp:28
bool parseLineSegments(std::ifstream &in, std::vector< MeshLib::Node * > &nodes, std::vector< MeshLib::Element * > &elems, std::map< std::size_t, std::size_t > const &node_id_map, MeshLib::Properties &mesh_prop)
Parses the segments of the current line.
bool parseLine(std::ifstream &in, std::vector< MeshLib::Node * > &nodes, std::vector< MeshLib::Element * > &elems, std::map< std::size_t, std::size_t > &node_id_map, MeshLib::Properties &mesh_prop)
Parses line information (nodes, segments, properties)
bool parseNodes(std::ifstream &in, std::vector< MeshLib::Node * > &nodes, std::map< std::size_t, std::size_t > &node_id_map, MeshLib::Properties const &mesh_prop)
Parses the node data for the current mesh.

References eof_error, ERR(), parseLine(), parseLineSegments(), parseNodes(), BaseLib::splitString(), and WARN().

Referenced by parseLine(), and readData().

◆ parseLineSegments()

bool FileIO::Gocad::GocadAsciiReader::parseLineSegments ( std::ifstream &  in,
std::vector< MeshLib::Node * > &  nodes,
std::vector< MeshLib::Element * > &  elems,
std::map< std::size_t, std::size_t > const &  node_id_map,
MeshLib::Properties mesh_prop 
)

Parses the segments of the current line.

Definition at line 357 of file GocadAsciiReader.cpp.

362{
364 *mesh_prop.getPropertyVector<int>(mat_id_name);
365 int current_mat_id(0);
366 if (!mat_ids.empty())
367 {
368 current_mat_id = (*std::max_element(mat_ids.begin(), mat_ids.end()))++;
369 }
370 std::streampos pos = in.tellg();
371 std::size_t id(0);
372 std::string line;
373 while (std::getline(in, line))
374 {
375 if (line.empty() || isCommentLine(line))
376 {
377 continue;
378 }
379 if (line.substr(0, 3) == "SEG")
380 {
381 std::stringstream sstr(line);
382 std::string keyword;
383 std::array<std::size_t, 2> data{};
384 sstr >> keyword >> data[0] >> data[1];
385 std::array<MeshLib::Node*, 2> elem_nodes{};
386 for (std::size_t i = 0; i < 2; ++i)
387 {
388 auto const it = node_id_map.find(data[i]);
389 if (it == node_id_map.end() || it->second >= nodes.size())
390 {
391 ERR("Error: Node ID ({:d}) out of range (0, {:d}).",
392 data[i], nodes.back()->getID());
393 return false;
394 }
395 elem_nodes[i] = nodes[it->second];
396 }
397 elems.push_back(new MeshLib::Line(elem_nodes, id++));
398 mat_ids.push_back(current_mat_id);
399 }
400 else
401 {
402 in.seekg(pos);
403 return true;
404 }
405 pos = in.tellg();
406 }
407 ERR("{:s}", eof_error);
408 return false;
409}

References eof_error, ERR(), MeshLib::Properties::getPropertyVector(), isCommentLine(), and mat_id_name.

Referenced by parseLine().

◆ parseNodes()

bool FileIO::Gocad::GocadAsciiReader::parseNodes ( std::ifstream &  in,
std::vector< MeshLib::Node * > &  nodes,
std::map< std::size_t, std::size_t > &  node_id_map,
MeshLib::Properties const &  mesh_prop 
)

Parses the node data for the current mesh.

Definition at line 277 of file GocadAsciiReader.cpp.

281{
282 NodeType t = NodeType::UNSPECIFIED;
283 std::streampos pos = in.tellg();
284 std::string line;
285 while (std::getline(in, line))
286 {
287 std::vector<std::string> str = BaseLib::splitString(line);
288 if (line.substr(0, 3) == "SEG" || line.substr(0, 4) == "TRGL")
289 {
290 in.seekg(pos);
291 return true;
292 }
293
294 if (line.substr(0, 28) == "BEGIN_ATOM_REGION_INDICATORS")
295 {
297 {
298 ERR("File ended while parsing Atom Region Indicators...");
299 return false;
300 }
301 return true;
302 }
303
304 if (line.empty() || isCommentLine(line))
305 {
306 continue;
307 }
308 if (!(line.substr(0, 4) == "VRTX" || line.substr(0, 5) == "PVRTX" ||
309 line.substr(0, 4) == "ATOM"))
310 {
311 WARN("GocadAsciiReader::parseNodes() - Unknown keyword found: {:s}",
312 line);
313 continue;
314 }
315
316 std::stringstream sstr(line);
317 if (line.substr(0, 4) == "VRTX" && t != NodeType::PVRTX)
318 {
319 t = NodeType::VRTX;
320 nodes.push_back(createNode(sstr));
321 }
322 else if (line.substr(0, 5) == "PVRTX" && t != NodeType::VRTX)
323 {
324 t = NodeType::PVRTX;
325 nodes.push_back(createNode(sstr));
326 for (auto [name, property] : mesh_prop)
327 {
328 if (name == mat_id_name)
329 {
330 continue;
331 }
332 if (auto p = dynamic_cast<MeshLib::PropertyVector<double>*>(
333 property))
334 {
335 double value;
336 sstr >> value;
337 p->push_back(value);
338 }
339 }
340 }
341 else if (line.substr(0, 4) == "ATOM")
342 {
343 std::size_t new_id;
344 std::size_t ref_id;
345 std::string keyword;
346 sstr >> keyword >> new_id >> ref_id;
347 nodes.push_back(new MeshLib::Node(nodes[ref_id]->data(), new_id));
348 }
349 node_id_map[nodes.back()->getID()] = nodes.size() - 1;
350 pos = in.tellg();
351 }
352 ERR("{:s}", eof_error);
353 return false;
354}
bool parseAtomRegionIndicators(std::ifstream &in)
MeshLib::Node * createNode(std::stringstream &sstr)
static const double p

References createNode(), eof_error, ERR(), isCommentLine(), mat_id_name, MaterialPropertyLib::name, parseAtomRegionIndicators(), PVRTX, BaseLib::splitString(), MathLib::t, UNSPECIFIED, VRTX, and WARN().

Referenced by parseLine(), and parseSurface().

◆ parseProperties()

bool FileIO::Gocad::GocadAsciiReader::parseProperties ( std::ifstream &  in,
std::vector< std::string > const &  names,
MeshLib::Properties mesh_prop 
)

Parses information of node properties. Only property names and array sizes are currently used.

Definition at line 201 of file GocadAsciiReader.cpp.

204{
205 // Because properties have no end-tag, the position of the last line is
206 // stored, so the stream can be set back if none of the allowed property-
207 // related keywords is found.
208 std::streampos pos = in.tellg();
209 std::string line;
210 while (getline(in, line))
211 {
212 std::string const key = propertyCheck(line);
213 // This is the intended way to exit this method:
214 // No property-related keyword has been found, so the stream is set
215 // back one line and the (unrelated) keyword can be read again in the
216 // parent method.
217 if (key.empty())
218 {
219 in.seekg(pos);
220 return true;
221 }
222
223 // Currently all property parameters except array name and size are
224 // ignored.
225 if (key == "ESIZES")
226 {
227 std::vector<std::string> prop_size = BaseLib::splitString(line);
228
229 if (names.size() != prop_size.size())
230 {
231 ERR("Error: Number of PROPERTY-names ({:d}) does not match "
232 "number of ESIZES ({:d})",
233 names.size(), prop_size.size());
234 return false;
235 }
236 std::size_t const n_names(names.size());
237 for (std::size_t i = 1; i < n_names; ++i)
238 {
239 mesh_prop.createNewPropertyVector<double>(
240 names[i],
242 BaseLib::str2number<std::size_t>(prop_size[i]));
243 }
244 }
245 // Remember current position in case the properties black ends now.
246 pos = in.tellg();
247 }
248 ERR("{:s}", eof_error);
249 return false;
250}
PropertyVector< T > * createNewPropertyVector(std::string const &name, MeshItemType mesh_item_type, std::size_t n_components=1)
std::string propertyCheck(std::string const &string)
Checks if the current line starts with one of the allowed keywords.

References MeshLib::Properties::createNewPropertyVector(), eof_error, ERR(), MeshLib::Node, propertyCheck(), and BaseLib::splitString().

Referenced by readData().

◆ parsePropertyClass()

bool FileIO::Gocad::GocadAsciiReader::parsePropertyClass ( std::ifstream &  in)

Reads PROPERTY_CLASS_HEADER sections of the file. All this information is currently ignored.

Definition at line 168 of file GocadAsciiReader.cpp.

169{
170 std::string line;
171 while (std::getline(in, line))
172 {
173 if (line.substr(0, 1) == "}")
174 {
175 return true;
176 }
177 }
178 ERR("{:s}", eof_error);
179 return false;
180}

References eof_error, and ERR().

Referenced by readData().

◆ parseSurface()

bool FileIO::Gocad::GocadAsciiReader::parseSurface ( std::ifstream &  in,
std::vector< MeshLib::Node * > &  nodes,
std::vector< MeshLib::Element * > &  elems,
std::map< std::size_t, std::size_t > &  node_id_map,
MeshLib::Properties mesh_prop 
)

Parses the surface information (nodes, triangles, properties)

Definition at line 503 of file GocadAsciiReader.cpp.

508{
509 if (!parseNodes(in, nodes, node_id_map, mesh_prop))
510 {
511 return false;
512 }
513 if (!parseElements(in, nodes, elems, node_id_map, mesh_prop))
514 {
515 return false;
516 }
517
518 std::string line;
519 while (std::getline(in, line))
520 {
521 std::vector<std::string> str = BaseLib::splitString(line);
522 if (str[0] == "TFACE")
523 {
524 parseSurface(in, nodes, elems, node_id_map, mesh_prop);
525 return true;
526 }
527 if (str[0] == "BSTONE")
528 {
529 // borderstone definition - currently ignored
530 }
531 else if (str[0] == "BORDER")
532 {
533 // border tracking direction - currently ignored
534 }
535 else if (line == "END")
536 {
537 return true;
538 }
539 else
540 {
541 WARN(
542 "GocadAsciiReader::parseSurface() - Unknown keyword found: "
543 "{:s}",
544 line);
545 }
546 }
547 ERR("{:s}", eof_error);
548 return false;
549}
bool parseElements(std::ifstream &in, std::vector< MeshLib::Node * > &nodes, std::vector< MeshLib::Element * > &elems, std::map< std::size_t, std::size_t > const &node_id_map, MeshLib::Properties &mesh_prop)
Parses the element data for the current mesh.
bool parseSurface(std::ifstream &in, std::vector< MeshLib::Node * > &nodes, std::vector< MeshLib::Element * > &elems, std::map< std::size_t, std::size_t > &node_id_map, MeshLib::Properties &mesh_prop)
Parses the surface information (nodes, triangles, properties)

References eof_error, ERR(), parseElements(), parseNodes(), parseSurface(), BaseLib::splitString(), and WARN().

Referenced by parseSurface(), and readData().

◆ propertyCheck()

std::string FileIO::Gocad::GocadAsciiReader::propertyCheck ( std::string const &  string)

Checks if the current line starts with one of the allowed keywords.

Definition at line 183 of file GocadAsciiReader.cpp.

184{
185 std::array<std::string, 7> const property_keywords = {
186 {"PROPERTY_CLASSES", "PROP_LEGAL_RANGES", "NO_DATA_VALUES",
187 "PROPERTY_KINDS", "PROPERTY_SUBCLASSES", "UNITS", "ESIZES"}};
188
189 std::string const str = BaseLib::splitString(string)[0];
190 auto res =
191 std::find(property_keywords.begin(), property_keywords.end(), str);
192 if (res != property_keywords.end())
193 {
194 return *res;
195 }
196 return std::string("");
197}

References BaseLib::splitString().

Referenced by parseProperties().

◆ readData()

MeshLib::Mesh * FileIO::Gocad::GocadAsciiReader::readData ( std::ifstream &  in,
DataType const &  type,
std::string &  mesh_name 
)

Reads one mesh contained in the file (there may be more than one!)

Definition at line 580 of file GocadAsciiReader.cpp.

583{
584 if (!parseHeader(in, mesh_name))
585 {
586 return nullptr;
587 }
588
589 MeshLib::Properties mesh_prop;
592 bool flip_elevation = false;
593 std::string line;
594 while (std::getline(in, line))
595 {
596 std::vector<std::string> str = BaseLib::splitString(line);
597 if (line.empty() || isCommentLine(line))
598 {
599 continue;
600 }
601 if (str[0] == "GOCAD_ORIGINAL_COORDINATE_SYSTEM")
602 {
603 CoordinateSystem coordinate_system;
604 if (!coordinate_system.parse(in))
605 {
606 ERR("Error parsing coordinate system.");
607 return nullptr;
608 }
609 flip_elevation = (coordinate_system.z_positive ==
610 CoordinateSystem::ZPOSITIVE::Depth);
611 }
612 else if (str[0] == "GEOLOGICAL_FEATURE" ||
613 str[0] == "GEOLOGICAL_TYPE" ||
614 str[0] == "STRATIGRAPHIC_POSITION" || str[0] == "REGION")
615 {
616 // geological and stratigraphic information - currently ignored
617 }
618 else if (str[0] == "PROPERTY_CLASS_HEADER")
619 {
620 if (!parsePropertyClass(in))
621 {
622 ERR("Error parsing PROPERTY_CLASS_HEADER.");
623 return nullptr;
624 }
625 }
626 else if (str[0] == "PROPERTIES")
627 {
628 if (!parseProperties(in, str, mesh_prop))
629 {
630 ERR("Error parsing PROPERTIES");
631 return nullptr;
632 }
633 }
634 else if (type == DataType::PLINE && str[0] == "ILINE")
635 {
636 return createMesh(in, type, mesh_name, mesh_prop, parseLine,
637 flip_elevation);
638 }
639 else if (type == DataType::TSURF && str[0] == "TFACE")
640 {
641 return createMesh(in, type, mesh_name, mesh_prop, parseSurface,
642 flip_elevation);
643 }
644 else
645 {
646 WARN("GocadAsciiReader::readData() - Unknown keyword found: {:s}",
647 line);
648 }
649 }
650 ERR("{:s}", eof_error);
651 return nullptr;
652}
Property manager on mesh items. Class Properties manages scalar, vector or matrix properties....
Definition: Properties.h:36
bool parseHeader(std::ifstream &in, std::string &mesh_name)
Parses the HEADER section (everything except the name is ignored right now)
bool parsePropertyClass(std::ifstream &in)
bool parseProperties(std::ifstream &in, std::vector< std::string > const &names, MeshLib::Properties &mesh_prop)
MeshLib::Mesh * createMesh(std::ifstream &in, DataType type, std::string &mesh_name, MeshLib::Properties &mesh_prop, T parser, bool const flip_elevation)
Converts parsed data into mesh.

References MeshLib::Cell, createMesh(), MeshLib::Properties::createNewPropertyVector(), FileIO::Gocad::CoordinateSystem::Depth, eof_error, ERR(), isCommentLine(), mat_id_name, FileIO::Gocad::CoordinateSystem::parse(), parseHeader(), parseLine(), parseProperties(), parsePropertyClass(), parseSurface(), FileIO::Gocad::PLINE, BaseLib::splitString(), FileIO::Gocad::TSURF, WARN(), and FileIO::Gocad::CoordinateSystem::z_positive.

Referenced by readFile().

◆ readFile()

bool FileIO::Gocad::GocadAsciiReader::readFile ( std::string const &  file_name,
std::vector< std::unique_ptr< MeshLib::Mesh > > &  meshes,
DataType const  export_type 
)

Reads the specified file and writes data into internal mesh vector.

Definition at line 654 of file GocadAsciiReader.cpp.

657{
658 std::ifstream in(file_name);
659 if (!in.is_open())
660 {
661 ERR("GocadAsciiReader::readFile(): Could not open file {:s}.",
662 file_name);
663 return false;
664 }
665
666 checkLineEndings(file_name);
667
668 DataType type;
669 while ((type = datasetFound(in)) != DataType::UNDEFINED)
670 {
671 if (export_type != DataType::ALL && type != export_type)
672 {
673 skipToEND(in);
674 continue;
675 }
676
677 if (type == DataType::VSET || type == DataType::MODEL3D)
678 {
679 if (!skipToEND(in))
680 {
681 ERR("Parsing of type {:s} is not implemented. Skipping "
682 "section.",
683 dataType2String(type));
684 return false;
685 }
686 continue;
687 }
688
689 std::string mesh_name = BaseLib::dropFileExtension(file_name) +
690 std::to_string(meshes.size() + 1);
691 std::unique_ptr<MeshLib::Mesh> mesh(readData(in, type, mesh_name));
692 if (mesh == nullptr)
693 {
694 ERR("File parsing aborted...");
695 return false;
696 }
697 meshes.push_back(std::move(mesh));
698 }
699 checkMeshNames(meshes);
700 return true;
701}
std::string dropFileExtension(std::string const &filename)
Definition: FileTools.cpp:169
void checkLineEndings(std::string const &file_name)
Checks if current line is a designated keyword for a GoCAD data set.
bool skipToEND(std::ifstream &in)
Parses current section until END-tag is reached.
void checkMeshNames(std::vector< std::unique_ptr< MeshLib::Mesh > > const &meshes)
MeshLib::Mesh * readData(std::ifstream &in, DataType const &type, std::string &mesh_name)
Reads one mesh contained in the file (there may be more than one!)
DataType datasetFound(std::ifstream &in)
Checks if a GoCAD data set begins at the current stream position.

References FileIO::Gocad::ALL, checkLineEndings(), checkMeshNames(), datasetFound(), FileIO::Gocad::dataType2String(), BaseLib::dropFileExtension(), ERR(), FileIO::Gocad::MODEL3D, readData(), skipToEND(), FileIO::Gocad::UNDEFINED, and FileIO::Gocad::VSET.

Referenced by MainWindow::loadFile(), main(), FileIO::XmlPrjInterface::readFile(), GeoLib::IO::XmlGmlInterface::readFile(), and GeoLib::IO::XmlStnInterface::readFile().

◆ skipToEND()

bool FileIO::Gocad::GocadAsciiReader::skipToEND ( std::ifstream &  in)

Parses current section until END-tag is reached.

Definition at line 68 of file GocadAsciiReader.cpp.

69{
70 std::string line;
71 while (std::getline(in, line))
72 {
73 if (line == "END")
74 {
75 return true;
76 }
77 }
78 ERR("{:s}", eof_error);
79 return false;
80}

References eof_error, and ERR().

Referenced by readFile().

Variable Documentation

◆ eof_error

const std::string FileIO::Gocad::GocadAsciiReader::eof_error = "Error: Unexpected end of file."

◆ mat_id_name

const std::string FileIO::Gocad::GocadAsciiReader::mat_id_name = "MaterialIDs"

Definition at line 37 of file GocadAsciiReader.cpp.

Referenced by parseElements(), parseLineSegments(), parseNodes(), and readData().