File indexing completed on 2025-01-18 09:13:03
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include <iostream>
0012 #include <sstream>
0013 #include <string>
0014 #include <vector>
0015
0016 #include <boost/algorithm/string.hpp>
0017
0018 namespace Acts::Test {
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 inline static std::vector<std::string> testObjString(const std::string& tString,
0039 bool triMesh = false) {
0040 std::vector<std::string> errorStrings;
0041 const std::string w = "[ Invalid obj : ";
0042
0043 std::vector<std::string> passes = {"#", "usemtl", "mtllib", "o", "g", "s"};
0044
0045 auto ss = std::stringstream{tString};
0046 for (std::string line; std::getline(ss, line, '\n');) {
0047 auto fnbc = line.find_first_not_of(" ", 0);
0048 if (fnbc != std::string::npos) {
0049 auto snbc = line.find_first_of(" ", fnbc);
0050 std::string stag = line.substr(fnbc, snbc - fnbc);
0051
0052
0053 bool pass(false);
0054 for (const auto& ptag : passes) {
0055 if (ptag == stag) {
0056 pass = true;
0057 break;
0058 }
0059 }
0060 if (pass) {
0061 continue;
0062 }
0063
0064 auto tnbc = line.find_first_not_of(" ", snbc);
0065 std::string body = line.substr(tnbc, line.size() - tnbc);
0066
0067
0068 if (stag.find("v") != std::string::npos ||
0069 (stag == std::string("f") && triMesh)) {
0070 std::vector<std::string> bodySplit;
0071 boost::split(bodySplit, body, boost::is_any_of(" "));
0072 if (bodySplit.size() != 3 && stag != std::string("f")) {
0073 errorStrings.push_back(w + line + " ] " + stag +
0074 " must only have three attributes!");
0075 } else if (bodySplit.size() != 3) {
0076 errorStrings.push_back("[ not a triangular mesh : " + line + " ]");
0077 }
0078 continue;
0079 }
0080
0081
0082 if (stag == std::string("f") || stag == std::string("l")) {
0083 bool onlyDigits =
0084 (body.find_first_not_of("0123456789/ ") == std::string::npos);
0085 if (!onlyDigits) {
0086 errorStrings.push_back(w + line + " ] " + stag +
0087 " can only have positive integers!");
0088 }
0089 std::vector<std::string> bodySplit;
0090 boost::split(bodySplit, body, boost::is_any_of(" "));
0091 for (auto& bs : bodySplit) {
0092 if (bs == "0") {
0093 errorStrings.push_back(w + line +
0094 " ] vertex with index 0 detected!");
0095 }
0096 }
0097 continue;
0098 }
0099 errorStrings.push_back(w + line + " ] invalid syntax!");
0100 }
0101 }
0102 return errorStrings;
0103 }
0104
0105
0106 struct PlyElement {
0107 std::string name = "none";
0108 std::size_t copies = 0;
0109 int properties = 0;
0110 };
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122 inline static std::vector<std::string> testPlyString(const std::string& tString,
0123 bool = false) {
0124 std::vector<std::string> errorStrings;
0125 const std::string w = "[ Invalid ply : ";
0126
0127 std::vector<std::string> hPasses = {"format", "comment"};
0128
0129 auto ss = std::stringstream{tString};
0130 bool inHeader = false;
0131
0132 std::size_t lNumber = 0;
0133 std::size_t cElement = 0;
0134 std::vector<PlyElement> elements;
0135 PlyElement currentElement;
0136
0137 for (std::string line; std::getline(ss, line, '\n'); ++lNumber) {
0138
0139 if (lNumber == 0 && line != "ply") {
0140 errorStrings.push_back(w + line + " ] first line has to be 'ply");
0141 } else if (line == "ply") {
0142 inHeader = true;
0143 cElement = 0;
0144 elements.clear();
0145 continue;
0146 }
0147
0148 if (inHeader) {
0149 auto fnbc = line.find_first_not_of(" ", 0);
0150 if (fnbc != std::string::npos) {
0151 auto snbc = line.find_first_of(" ", fnbc);
0152 std::string stag = line.substr(fnbc, snbc - fnbc);
0153 if (stag == "comment" || stag == "format") {
0154 continue;
0155 }
0156 if (stag == "end_header") {
0157 inHeader = false;
0158 elements.push_back(currentElement);
0159 currentElement = PlyElement();
0160 continue;
0161 }
0162
0163 auto tnbc = line.find_first_not_of(" ", snbc);
0164 std::string body = line.substr(tnbc, line.size() - tnbc);
0165
0166 auto n0nbc = body.find_first_not_of(" ", 0);
0167 auto n1nbc = body.find_first_of(" ", n0nbc);
0168 std::string name = body.substr(n0nbc, n1nbc);
0169
0170 if (stag == "element") {
0171
0172 if (currentElement.name != "none" && currentElement.copies > 0) {
0173 elements.push_back(currentElement);
0174 currentElement = PlyElement();
0175 }
0176 currentElement.name = name;
0177
0178 auto n2nbc = body.find_first_of(" ", n1nbc);
0179 std::string copies = body.substr(n1nbc, n2nbc);
0180 currentElement.copies = std::stoi(copies);
0181 } else if (stag == "property") {
0182 if (name == "list") {
0183 currentElement.properties = -1;
0184 continue;
0185 }
0186 if (currentElement.properties >= 0) {
0187 ++currentElement.properties;
0188 }
0189 } else {
0190 errorStrings.push_back(w + line + " ] Unknown command.");
0191 }
0192 }
0193 } else {
0194 if (elements[cElement].copies == 0) {
0195 ++cElement;
0196 }
0197 if (cElement < elements.size()) {
0198 elements[cElement].copies -= 1;
0199 std::vector<std::string> lineSplit;
0200 boost::split(lineSplit, line, boost::is_any_of(" "));
0201 if (elements[cElement].properties == -1) {
0202 int nprops = std::stoi(lineSplit[0]);
0203 if (nprops != (static_cast<int>(lineSplit.size()) - 1)) {
0204 errorStrings.push_back(w + line + std::string(" ] List expected ") +
0205 std::to_string(nprops) +
0206 std::string(" properties, while found ") +
0207 std::to_string(lineSplit.size() - 1) +
0208 std::string("."));
0209 }
0210 } else if (lineSplit.size() !=
0211 static_cast<std::size_t>(elements[cElement].properties)) {
0212 errorStrings.push_back(
0213 w + line + std::string(" ] Element expected ") +
0214 std::to_string(elements[cElement].properties) +
0215 std::string(" properties, while found ") +
0216 std::to_string(lineSplit.size()) + std::string("."));
0217 }
0218 }
0219 }
0220 }
0221
0222 return errorStrings;
0223 }
0224
0225 }