#include "boost/regex.hpp" #include #include "case_reader.h" #include "fstream" #include "vector" CaseReader::CaseReader(const string &filePath, int ptDim) { srf1.ptDim = ptDim; srf2.ptDim = ptDim; initVertices1(handleFile(filePath)); } CaseReader::CaseReader(const string &filePath1, const string &filePath2, int ptDim) { srf1.ptDim = ptDim; srf2.ptDim = ptDim; initVertices2(handleFile(filePath1), srf1); initVertices2(handleFile(filePath2), srf2); } string CaseReader::handleFile(const string &filePath) { ifstream fin; fin.open(filePath); if (!fin) { cout << "File Open Error!" << endl; } string str; string tmp; while (fin.good()) { getline(fin, tmp); str += tmp + "\n"; } fin.close(); // initVertices1(str); return str; } void CaseReader::initVertices1(const string &str) { vector infos; boost::algorithm::split(infos, str, boost::is_any_of(";")); auto wData = infos[0], srf1Data = infos[1], srf2Data = infos[2]; getPtsFromStr1(srf1Data, srf1); getPtsFromStr1(srf2Data, srf2); wData = regex_replace(wData, boost::regex(R"((^(.)*Matrix( )*\(( )*\[( )*\[)|(\]( )*\]( )*\)( )*(.)*$))"), ""); vector ws; split_regex(ws, wData, boost::regex("( )*\\]( )*,( )*\\[( )*")); for (int i = 0; i < ws.size(); i++) { vector lineWs; split_regex(lineWs, ws[i], boost::regex("( )*,( )*")); for (int j = 0; j < lineWs.size(); j++) { int baseIdx = (i * static_cast(lineWs.size()) + j) * 4; srf1.vertex[baseIdx + 3] = stod(lineWs[j]); srf1.vertex[baseIdx] *= srf1.vertex[baseIdx + 3]; srf1.vertex[baseIdx + 1] *= srf1.vertex[baseIdx + 3]; srf1.vertex[baseIdx + 2] *= srf1.vertex[baseIdx + 3]; srf2.vertex[baseIdx + 3] = stod(lineWs[j]); srf2.vertex[baseIdx] *= srf2.vertex[baseIdx + 3]; srf2.vertex[baseIdx + 1] *= srf2.vertex[baseIdx + 3]; srf2.vertex[baseIdx + 2] *= srf2.vertex[baseIdx + 3]; printf("(%g, %g, %g, %g) ", srf1.vertex[baseIdx], srf1.vertex[baseIdx + 1], srf1.vertex[baseIdx + 2], srf1.vertex[baseIdx + 3]); } // printf("\n"); } } void CaseReader::getPtsFromStr1(string &srfData, Srf &srf) { srfData = regex_replace(srfData, boost::regex("^(.)*Matrix( )*\\("), ""); srfData = regex_replace(srfData, boost::regex("\\}( )*\\)$"), ""); vector dimsAndPts; split_regex(dimsAndPts, srfData, boost::regex("( )*\\{( )*")); auto dimsData = dimsAndPts[0]; auto ptsData = dimsAndPts[1]; vector dims; split_regex(dims, dimsData, boost::regex("( )*,( )*")); srf.dim_u = stoi(dims[0]); srf.dim_v = stoi(dims[1]); // 默认bezier // srf.degree_u = srf.dim_u - 1; // srf.degree_v = srf.dim_v - 1; srf.degree_u = 3; srf.degree_v = 3; srf.knots_num_u = 2 + srf.dim_u + srf.degree_u + 1 - 2 * (srf.degree_u + 1); srf.knots_num_v = 2 + srf.dim_v + srf.degree_v + 1 - 2 * (srf.degree_v + 1); srf.knots_u = new double[srf.knots_num_u]; srf.knots_v = new double[srf.knots_num_v]; srf.knots_u[1] = 0.3; srf.knots_u[2] = 0.7; srf.knots_v[1] = 0.3; srf.knots_v[2] = 0.7; srf.knots_u[0] = 0; srf.knots_u[srf.knots_num_u-1] = 1; srf.knots_v[0] = 0; srf.knots_v[srf.knots_num_v-1] = 1; srf.knots_mult_u = new int[srf.knots_num_u]; srf.knots_mult_v = new int[srf.knots_num_v]; for(int i = 1; i < srf.knots_num_u-1; i++) srf.knots_mult_u[i] = 1; for(int i = 1; i < srf.knots_num_v-1; i++) srf.knots_mult_v[i] = 1; srf.knots_mult_u[0] = srf.degree_u + 1; srf.knots_mult_u[srf.knots_num_u-1] = srf.degree_u + 1; srf.knots_mult_v[0] = srf.degree_u + 1; srf.knots_mult_v[srf.knots_num_v-1] = srf.degree_v + 1; vector pts; split_regex(pts, ptsData, boost::regex("( )*,( )*\\(")); delete[] srf.vertex; srf.vertex = new double[srf.dim_u * srf.dim_v * srf.ptDim]; if (pts.size() != srf.dim_u * srf.dim_v) { printf("control points size error!\n"); } for (int i = 0; i < srf.dim_u; i++) { for (int j = 0; j < srf.dim_v; j++) { vector pt; split_regex(pt, pts[i * srf.dim_v + j], boost::regex("( )*=( )*")); auto ptCoords = pt[1]; boost::algorithm::erase_all(ptCoords, "["); boost::algorithm::erase_all(ptCoords, "]"); vector xyz; split_regex(xyz, ptCoords, boost::regex("( )*,( )*")); if (xyz.size() != 3) { printf("coord element cnt error!\n"); } for (int k = 0; k < 3; k++) { double num; auto coordChar = xyz[k]; if (coordChar.find('/') != string::npos) { vector nums; split_regex(nums, coordChar, boost::regex("( )*/( )*")); num = stod(nums[0]) / stod(nums[1]); } else { num = stod(coordChar); } srf.vertex[(i * srf.dim_v + j) * srf.ptDim + k] = num; } // printf("(%g, %g, %g) ", resVertex[(i * dim_v + j) * 4], resVertex[(i * dim_v + j) * 4 + 1], // resVertex[(i * dim_v + j) * 4 + 2]); } // printf("\n"); } // cout << "regex_match: " << boost::regex_match(srfData, expr) << endl; int a = 1; // std::string my_stringB = "2020 Happy New Year !!!"; // // boost::regex regxA("^(\\d| )*"); // 匹配开头数字 // boost::regex regxB("!*$"); // 匹配末尾标点符号 // // cout << regex_replace(my_stringB, regxA, "2021") << endl; // cout << regex_replace(my_stringB, regxB, "") << endl; } CaseReader::~CaseReader() { } double *CaseReader::getPtsFromStr2(string &srfData) { return nullptr; } void CaseReader::initVertices2(const string &str, Srf &srf) { boost::regex p(R"(-8\.\d+,)"); vector res; vector infos; // 将str中的信息以正则表达式nextLine为分隔符进行分割,存入infos中,这个真正表达式是\n或者\r或者\r\n三种换行符中的任意一种 // 这里真正表达式中三个子式的顺序非常重要,因为在匹配时,会按照子式的顺序进行匹配,如何\r在前,那么\r\n就不会匹配到,因为\r\n已经被\r匹配到了,但是\n还是会被匹配,这样就会被匹配两次,\r和\n之间会被分割出一个空串 boost::regex nextLine(R"(((\r\n)|(\r)|(\n))+)"); // boost::regex nextLine(R"(((\r)|(\r\n)|(\n)){1})"); boost::sregex_token_iterator it(str.begin(), str.end(), nextLine, -1); // -1表示不包含分隔符 boost::sregex_token_iterator end; for (; it != end; ++it) { infos.emplace_back(it->str()); } auto degrees = extractSubStr(infos[0], "\\d+"); srf.degree_u = stoi(degrees[0]); srf.degree_v = stoi(degrees[1]); auto dims = extractSubStr(infos[1], "\\d+"); srf.dim_u = stoi(dims[0]); srf.dim_v = stoi(dims[1]); // 最外面加了个括号是因为|的优先级很低,括号防止|并到更长的子式 string regexExprForNum = R"(-?((\d+\.?\d*)|(\d*\.?\d+)))"; auto knotsVec_u = extractSubStr(infos[2], regexExprForNum); vector knotsVec_mult_u; srf.knots_num_u = 0; for (int i = 0; i < knotsVec_u.size(); i++) { if (i == 0 || stod(knotsVec_u[i]) != stod(knotsVec_u[i - 1])) { // 用独特的值覆盖重复的值 knotsVec_u[srf.knots_num_u] = knotsVec_u[i]; srf.knots_num_u++; knotsVec_mult_u.emplace_back(1); } else { knotsVec_mult_u[srf.knots_num_u - 1]++; } } delete[] srf.knots_u; srf.knots_u = new double[srf.knots_num_u]; delete[] srf.knots_mult_u; srf.knots_mult_u = new int[srf.knots_num_u]; for (int i = 0; i < srf.knots_num_u; i++) { srf.knots_u[i] = stod(knotsVec_u[i]); srf.knots_mult_u[i] = knotsVec_mult_u[i]; } auto knotsVec_v = extractSubStr(infos[3], regexExprForNum); vector knotsVec_mult_v; srf.knots_num_v = 0; for (int i = 0; i < knotsVec_v.size(); i++) { if (i == 0 || stod(knotsVec_v[i]) != stod(knotsVec_v[i - 1])) { // 用独特的值覆盖重复的值 knotsVec_v[srf.knots_num_v] = knotsVec_v[i]; srf.knots_num_v++; knotsVec_mult_v.emplace_back(1); } else { knotsVec_mult_v[srf.knots_num_v - 1]++; } } delete[] srf.knots_v; srf.knots_v = new double[srf.knots_num_v]; delete[] srf.knots_mult_v; srf.knots_mult_v = new int[srf.knots_num_v]; for (int i = 0; i < srf.knots_num_v; i++) { srf.knots_v[i] = stod(knotsVec_v[i]); srf.knots_mult_v[i] = knotsVec_mult_v[i]; } if (knotsVec_u.size() != srf.dim_u + srf.degree_u + 1) { printf("knots_u size error!\n"); return; } if (knotsVec_v.size() != srf.dim_v + srf.degree_v + 1) { printf("knots_v size error!\n"); return; } delete[] srf.vertex; srf.vertex = new double[srf.dim_u * srf.dim_v * srf.ptDim]; // for (int i = 0; i < srf.dim_u; i++) { // auto regexExprForPt = regexExprForNum; // // 注意这里不能写成链式的,因为有append自己的操作,而每次append又会改变自己,就会造成重复append // regexExprForPt.append(", *"); // regexExprForPt.append(regexExprForNum); // regexExprForPt.append(", *"); // regexExprForPt.append(regexExprForNum); // auto pts = extractSubStr(infos[i + 4], regexExprForPt); // auto ws = extractSubStr(infos[i + 4 + srf.dim_u], regexExprForNum); // if (pts.size() != srf.dim_v) { // printf("control points size error!\n"); // return; // } // for (int j = 0; j < srf.dim_v; j++) { // auto pt = extractSubStr(pts[j], regexExprForNum); // auto w = stod(ws[j]); // for (int k = 0; k < 3; k++) { // srf.vertex[(i * srf.dim_v + j) * srf.ptDim + k] = w * stod(pt[k]); // } // if(srf.ptDim < 4) srf.vertex[(i * srf.dim_v + j) * srf.ptDim + 3] = w; // } // } auto regexExprForPt = regexExprForNum; regexExprForPt.append(", *"); regexExprForPt.append(regexExprForNum); regexExprForPt.append(", *"); regexExprForPt.append(regexExprForNum); auto pts = extractSubStr(infos[4], regexExprForPt); for (int i = 0; i < srf.dim_u; i++) { for (int j = 0; j < srf.dim_v; j++) { auto pt = extractSubStr(pts[i * srf.dim_v + j], regexExprForNum); for (int k = 0; k < 3; k++) { srf.vertex[(i * srf.dim_v + j) * srf.ptDim + k] = stod(pt[k]); } if(srf.ptDim < 4) srf.vertex[(i * srf.dim_v + j) * srf.ptDim + 3] = 1; } } // for (auto &s: res) { // cout << s << endl; // } // boost::smatch result; // std::string::const_iterator start = str.begin(); // std::string::const_iterator end = str.end(); // // while(boost::regex_search(start, end, result, p)) { // std::cout << result[0] << std::endl; // start = result[0].second; // res.emplace_back(result[0].str()); // } } // 使用boost提取str中匹配正则表达式的子串 vector CaseReader::extractSubStr(const string &str, const string ®exExpr) { vector res; boost::regex p(regexExpr); boost::sregex_token_iterator it(str.begin(), str.end(), p, 0); boost::sregex_token_iterator end; for (; it != end; ++it) { res.emplace_back(it->str()); } return res; }