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

#include <iostream>
#include "SingularityJudger.h"
#include "fstream"
#include "QString"
#include "QList"
#include "QRegularExpression"
#include "gauss_map.h"
SrfMesh getMesh(const RationalSurface<float> &s, int sampleLevel) {
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++) {
auto u = s_first_u + s_step_u * float(i);
for (int j = 0; j < res.sampleCntOnSingleDir; j++) {
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]));
}
}
return res;
}
array2<glm::vec3> getPtsFromStr(QString srfData);
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;
// 曲面s和f的法向量
const vector <vector<glm::vec3>> s_normal;
const vector <vector<glm::vec3>> f_normal;
auto mesh1 = getMesh(s, 7); // [0, 63]
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());
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;
}