Integration of gauss map, osculating toroidal patches, loop detection and C2 judgement to figure out the singular or loop intersection.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

212 lines
8.1 KiB

2 years ago
#include <iostream>
#include "SingularityJudger.h"
#include "fstream"
#include "QString"
#include "QList"
#include "QRegularExpression"
#include "gauss_map.h"
2 years ago
SrfMesh getMesh(const RationalSurface<float> &s, int sampleLevel) {
2 years ago
SrfMesh res;
res.sampleLevel = sampleLevel;
res.sampleCntOnSingleDir = int(pow(2, sampleLevel - 1) + 1);
res.evaluation = vector<vector<glm::vec3>>(res.sampleCntOnSingleDir, vector<glm::vec3>(res.sampleCntOnSingleDir));
res.tangent_u = vector<vector<glm::vec3>>(res.sampleCntOnSingleDir, vector<glm::vec3>(res.sampleCntOnSingleDir));
res.tangent_v = vector<vector<glm::vec3>>(res.sampleCntOnSingleDir, vector<glm::vec3>(res.sampleCntOnSingleDir));
res.normal = vector<vector<glm::vec3>>(res.sampleCntOnSingleDir, vector<glm::vec3>(res.sampleCntOnSingleDir));
auto s_first_u = *(s.knots_u.begin());
auto s_first_v = *(s.knots_v.begin());
auto s_step_u = (*(s.knots_u.end() - 1) - s_first_u) / float(res.sampleCntOnSingleDir - 1);
auto s_step_v = (*(s.knots_v.end() - 1) - s_first_v) / float(res.sampleCntOnSingleDir - 1);
for (int i = 0; i < res.sampleCntOnSingleDir; i++) {
2 years ago
auto u = s_first_u + s_step_u * float(i);
for (int j = 0; j < res.sampleCntOnSingleDir; j++) {
2 years ago
auto v = s_first_v + s_step_v * float(j);
res.evaluation[i][j] = tinynurbs::surfacePoint(s, u, v);
auto der = tinynurbs::surfaceDerivatives(s, 1, u, v);
res.tangent_u[i][j] = der(1, 0);
res.tangent_v[i][j] = der(0, 1);
res.normal[i][j] = glm::normalize(glm::cross(res.tangent_u[i][j], res.tangent_v[i][j]));
2 years ago
}
}
return res;
2 years ago
}
array2<glm::vec3> getPtsFromStr(QString srfData);
2 years ago
int main() {
RationalSurface<float> s;
RationalSurface<float> f;
// s.degree_u = 3;
// s.degree_v = 3;
// s.knots_u = {0, 0, 0, 0, 1, 1, 1, 1};
// s.knots_v = {0, 0, 0, 0, 1, 1, 1, 1};
// s.control_points = {4, 4, {
// glm::vec3(0, 0.3, 0.9), glm::vec3(0, 0.6, 1), glm::vec3(0, 0.9, 1.1), glm::vec3(0, 1.2, 1),
// glm::vec3(0.33, 0.3, 0.12), glm::vec3(0.33, 0.6, 0.12), glm::vec3(0.33, 0.9, 0.12),
// glm::vec3(0.33, 1.2, 0.12),
// glm::vec3(0.66, 0.3, 0.12), glm::vec3(0.66, 0.6, 0.12), glm::vec3(0.66, 0.9, 0.12),
// glm::vec3(0.66, 1.2, 0.12),
// glm::vec3(1, 0.3, 0.8), glm::vec3(1, 0.6, 1), glm::vec3(1, 0.9, 1.1), glm::vec3(1, 1.2, 1)
// }};
// s.weights = {4, 4,
// {
// 1, 1, 1, 1,
// 1, 1, 1, 1,
// 1, 1, 1, 1,
// 1, 1, 1, 1,
// }
// };
//
// f.degree_u = 3;
// f.degree_v = 3;
// f.knots_u = {0, 0, 0, 0, 1, 1, 1, 1};
// f.knots_v = {0, 0, 0, 0, 1, 1, 1, 1};
// f.control_points = {4, 4, {
// glm::vec3(0, 0.2, 0.9), glm::vec3(0, 0.5, 1.8), glm::vec3(0, 0.8, 1.1), glm::vec3(0, 1.2, 1),
// glm::vec3(0.33, 0.2, 0.12), glm::vec3(0.33, 0.5, 0.42), glm::vec3(0.33, 0.9, -0.62),
// glm::vec3(0.33, 1.1, -1.756),
// glm::vec3(0.66, 0.2, 0.12), glm::vec3(0.66, 0.5, 0.42), glm::vec3(0.66, 0.9, -0.62),
// glm::vec3(0.66, 1.0, -1.756),
// glm::vec3(1, 0.2, 0.8), glm::vec3(1, 0.5, 1), glm::vec3(1, 0.9, 1.1), glm::vec3(1, 1.2, 1)
// }};
// f.weights = {4, 4,
// {
// 1, 1, 1, 1,
// 1, 1, 1, 1,
// 1, 1, 1, 1,
// 1, 1, 1, 1,
// }
// };
ifstream fin;
fin.open(R"(E:\qt\OpenGLDemo\surfacePlayer\assets\intersectTest\casea3\surfaces.txt)");
string str;
string tmp;
while (fin.good()) {
getline(fin, tmp);
str += tmp + "\n";
}
cout << str << endl;
auto infos = QString(str.c_str()).split(";");
auto wData = infos[0];
auto srf1Data = infos[1];
auto srf2Data = infos[2];
auto points1 = getPtsFromStr(srf1Data);
auto points2 = getPtsFromStr(srf2Data);
wData = wData.remove(0, wData.indexOf("Matrix") + 6).trimmed();
wData.remove(0, 3);
wData.remove(wData.size() - 3, 3);
auto wInfos = wData.split(QRegularExpression("\\]( )*,( )*\\["));
array2<float> weights;
vector<float> wArray(points1.cols() * points1.rows());
for (int i = 0; i < points1.cols(); i++) {
auto wsInV = wInfos[i].split(QRegularExpression("( )*,( )*"));
for (int j = 0; j < points1.rows(); j++) {
wArray[i * points1.rows() + j] = wsInV[j].toFloat();
}
}
weights = {points1.cols(), points2.rows(), wArray};
// knot
std::vector<float> knot_u(2 * points1.cols(), 1.);
for (int i = 0; i < knot_u.size() / 2; i++)knot_u[i] = 0;
std::vector<float> knot_v(2 * points1.rows(), 1.);
for (int i = 0; i < knot_v.size() / 2; i++)knot_v[i] = 0;
s.degree_u = knot_u.size() / 2 - 1;
s.degree_v = knot_v.size() / 2 - 1;
s.knots_u = knot_u;
s.knots_v = knot_v;
s.control_points = points1;
s.weights = weights;
f.degree_u = knot_u.size() / 2 - 1;
f.degree_v = knot_v.size() / 2 - 1;
f.knots_u = knot_u;
f.knots_v = knot_v;
f.control_points = points2;
f.weights = weights;
fin.close();
// ====================== 测试 =======================
vector <vector<glm::vec3>> s_evaluation;
vector <vector<glm::vec3>> f_evaluation;
// 曲面s和f的切向量。zd*-sznmj
vector <vector<glm::vec3>> s_tangent_v;
vector <vector<glm::vec3>> f_tangent_u;
const vector <vector<glm::vec3>> f_tangent_v;
2 years ago
// 曲面s和f的法向量
const vector <vector<glm::vec3>> s_normal;
const vector <vector<glm::vec3>> f_normal;
2 years ago
auto mesh1 = getMesh(s, 7); // [0, 63]
2 years ago
auto mesh2 = getMesh(f, 7);
SingularityJudger singularityJudger(s, f, mesh1, mesh2);
// auto hasSingularity = singularityJudger.judge({2,7}, {4,12}, {3, 9}, {10, 16});
// for(auto line: singularityJudger.judgeRes) {
// for(auto el: line) {
// cout<<el<<' ';
// }
// cout<<endl;
// }
// singularityJudger.judge({12, 48}, {12, 48}, {12, 48}, {12, 48});
singularityJudger.judge({0, 63}, {0, 63}, {0, 63}, {0, 63});
// ================== 测试对整个曲面,gauss能排除多少(或保留多少)==================
GaussMap gaussMap1(mesh1.normal);
GaussMap gaussMap2(mesh2.normal);
gaussMap1.build();
gaussMap2.build();
auto pairs = getOverlapLeafNodes(gaussMap1, gaussMap2);
printf("Gauss Map: keep %lld samples in totally %lld boxes\n", pairs.size(),
mesh1.normal.size() * mesh1.normal[0].size() * mesh2.normal.size() * mesh2.normal[0].size());
2 years ago
return 0;
}
array2<glm::vec3> getPtsFromStr(QString srfData) {
srfData = srfData.remove(0, srfData.indexOf("Matrix") + 6).trimmed();
// 去掉首尾的括号
srfData.remove(0, 1);
srfData.remove(srfData.size() - 1, 1);
auto srfInfos = srfData.split("{");
auto srfDimInfos = srfInfos[0].split(QRegularExpression(",( )*"));
auto dimU = srfDimInfos[0].toInt();
auto dimV = srfDimInfos[1].toInt();
auto srfPtInfo = srfInfos[1].remove(srfInfos[1].indexOf("}"), 1);
auto srfPtsInfos = srfPtInfo.split(QRegularExpression(",( )*\\("));
std::vector<glm::vec3> points(dimU * dimV, glm::vec3());
for (int i = 0; i < srfPtsInfos.size(); i++) {
auto pt = srfPtsInfos[i].split("=")[1].trimmed();
// 去掉首尾的方括号
pt.remove(0, 1);
pt.remove(pt.size() - 1, 1);
// int iu = i / dimU;
// int iv = i % dimU;
auto coords = pt.split(QRegularExpression(",( )*"));
for (int k = 0; k < 3; k++) {
float num;
if (coords[k].contains("/")) {
auto nums = coords[k].split("/");
num = nums[0].trimmed().toFloat() / nums[1].trimmed().toFloat();
} else {
num = coords[k].toFloat();
}
if (k == 0) points[i].x = num;
else if (k == 1) points[i].y = num;
else points[i].z = num;
}
}
array2<glm::vec3> res = {(size_t) dimU, (size_t) dimV, points};
return res;
}