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
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;
|
|
}
|