|
|
|
#include "boost/regex.hpp"
|
|
|
|
#include <boost/algorithm/string/regex.hpp>
|
|
|
|
#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<string> 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<string> ws;
|
|
|
|
split_regex(ws, wData, boost::regex("( )*\\]( )*,( )*\\[( )*"));
|
|
|
|
|
|
|
|
for (int i = 0; i < ws.size(); i++) {
|
|
|
|
vector<string> lineWs;
|
|
|
|
split_regex(lineWs, ws[i], boost::regex("( )*,( )*"));
|
|
|
|
for (int j = 0; j < lineWs.size(); j++) {
|
|
|
|
int baseIdx = (i * static_cast<int>(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<string> dimsAndPts;
|
|
|
|
split_regex(dimsAndPts, srfData, boost::regex("( )*\\{( )*"));
|
|
|
|
auto dimsData = dimsAndPts[0];
|
|
|
|
auto ptsData = dimsAndPts[1];
|
|
|
|
|
|
|
|
vector<string> 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<string> 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<string> 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<string> 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<string> 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<string> res;
|
|
|
|
|
|
|
|
vector<string> 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<int> 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<int> 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<string> CaseReader::extractSubStr(const string &str, const string ®exExpr) {
|
|
|
|
vector<string> 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;
|
|
|
|
}
|
|
|
|
|