EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Visualization3DTester.hpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file Visualization3DTester.hpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2020 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
9 #include <iostream>
10 #include <sstream>
11 #include <string>
12 
13 #include <boost/algorithm/string.hpp>
14 
15 namespace Acts {
16 
17 namespace Test {
18 
37 inline static std::vector<std::string> testObjString(const std::string& tString,
38  bool triMesh = false) {
39  std::vector<std::string> errorStrings;
40  const std::string w = "[ Invalid obj : ";
41 
42  std::vector<std::string> passes = {"#", "usemtl", "mtllib", "o", "g", "s"};
43 
44  auto ss = std::stringstream{tString};
45  for (std::string line; std::getline(ss, line, '\n');) {
46  auto fnbc = line.find_first_not_of(" ", 0);
47  if (fnbc != std::string::npos) {
48  auto snbc = line.find_first_of(" ", fnbc);
49  std::string stag = line.substr(fnbc, snbc - fnbc);
50 
51  // Ignore comment line, usemtl, mtllib
52  bool pass(false);
53  for (const auto& ptag : passes) {
54  if (ptag == stag) {
55  pass = true;
56  break;
57  }
58  }
59  if (pass) {
60  continue;
61  }
62 
63  auto tnbc = line.find_first_not_of(" ", snbc);
64  std::string body = line.substr(tnbc, line.size() - tnbc);
65 
66  // Check if we have triplets
67  if (stag.find("v") != std::string::npos or
68  (stag == std::string("f") and triMesh)) {
69  std::vector<std::string> bodySplit;
70  boost::split(bodySplit, body, boost::is_any_of(" "));
71  if (bodySplit.size() != 3 and stag != std::string("f")) {
72  errorStrings.push_back(w + line + " ] " + stag +
73  " must only have three attributes!");
74  } else if (bodySplit.size() != 3) {
75  errorStrings.push_back("[ not a triangular mesh : " + line + " ]");
76  }
77  continue;
78  }
79  // Check if face and line only have positive integer numbers > 1
80  // or deliminator " ", " /"
81  if (stag == std::string("f") or stag == std::string("l")) {
82  bool onlyDigits =
83  (body.find_first_not_of("0123456789/ ") == std::string::npos);
84  if (!onlyDigits) {
85  errorStrings.push_back(w + line + " ] " + stag +
86  " can only have positive integers!");
87  }
88  std::vector<std::string> bodySplit;
89  boost::split(bodySplit, body, boost::is_any_of(" "));
90  for (auto& bs : bodySplit) {
91  if (bs == "0") {
92  errorStrings.push_back(w + line +
93  " ] vertex with index 0 detected!");
94  }
95  }
96  continue;
97  }
98  errorStrings.push_back(w + line + " ] invalid syntax!");
99  }
100  }
101  return errorStrings;
102 }
103 
105 struct PlyElement {
106  std::string name = "none";
107  size_t copies = 0;
108  int properties = 0; // -1 for list
109 };
110 
121 inline static std::vector<std::string> testPlyString(const std::string& tString,
122  bool triMesh = false) {
123  std::vector<std::string> errorStrings;
124  const std::string w = "[ Invalid ply : ";
125 
126  std::vector<std::string> hPasses = {"format", "comment"};
127 
128  auto ss = std::stringstream{tString};
129  bool inHeader = false;
130 
131  size_t lNumber = 0;
132  size_t cElement = 0;
133  std::vector<PlyElement> elements;
134  PlyElement currentElement;
135 
136  for (std::string line; std::getline(ss, line, '\n'); ++lNumber) {
137  // Check the "ply" statement at the beginning of the file
138  if (lNumber == 0 and line != "ply") {
139  errorStrings.push_back(w + line + " ] first line has to be 'ply");
140  } else if (line == "ply") {
141  inHeader = true;
142  cElement = 0;
143  elements.clear();
144  continue;
145  }
146  // Process the header
147  if (inHeader) {
148  auto fnbc = line.find_first_not_of(" ", 0);
149  if (fnbc != std::string::npos) {
150  auto snbc = line.find_first_of(" ", fnbc);
151  std::string stag = line.substr(fnbc, snbc - fnbc);
152  if (stag == "comment" or stag == "format") {
153  continue;
154  }
155  if (stag == "end_header") {
156  inHeader = false;
157  elements.push_back(currentElement);
158  currentElement = PlyElement();
159  continue;
160  }
161 
162  auto tnbc = line.find_first_not_of(" ", snbc);
163  std::string body = line.substr(tnbc, line.size() - tnbc);
164 
165  auto n0nbc = body.find_first_not_of(" ", 0);
166  auto n1nbc = body.find_first_of(" ", n0nbc);
167  std::string name = body.substr(n0nbc, n1nbc);
168 
169  if (stag == "element") {
170  // new element write the old one
171  if (currentElement.name != "none" and currentElement.copies > 0) {
172  elements.push_back(currentElement);
173  currentElement = PlyElement();
174  }
175  currentElement.name = name;
176  // get the number of copies
177  auto n2nbc = body.find_first_of(" ", n1nbc);
178  std::string copies = body.substr(n1nbc, n2nbc);
179  currentElement.copies = std::stoi(copies);
180  } else if (stag == "property") {
181  if (name == "list") {
182  currentElement.properties = -1;
183  continue;
184  }
185  if (currentElement.properties >= 0) {
186  ++currentElement.properties;
187  }
188  } else {
189  errorStrings.push_back(w + line + " ] Unkown command.");
190  }
191  }
192  } else {
193  if (elements[cElement].copies == 0) {
194  ++cElement;
195  }
196  if (cElement < elements.size()) {
197  elements[cElement].copies -= 1;
198  std::vector<std::string> lineSplit;
199  boost::split(lineSplit, line, boost::is_any_of(" "));
200  if (elements[cElement].properties == -1) {
201  int nprops = std::stoi(lineSplit[0]);
202  if (nprops != (int(lineSplit.size()) - 1)) {
203  errorStrings.push_back(w + line + std::string(" ] List expected ") +
204  std::to_string(nprops) +
205  std::string(" properties, while found ") +
206  std::to_string(lineSplit.size() - 1) +
207  std::string("."));
208  }
209  } else if (lineSplit.size() != size_t(elements[cElement].properties)) {
210  errorStrings.push_back(
211  w + line + std::string(" ] Element expected ") +
212  std::to_string(elements[cElement].properties) +
213  std::string(" propertes, while found ") +
214  std::to_string(lineSplit.size()) + std::string("."));
215  }
216  }
217  }
218  }
219 
220  (void)triMesh;
221 
222  return errorStrings;
223 }
224 
225 } // namespace Test
226 
227 } // namespace Acts